Пульт.Онлайн /

api.c

#include "header.h" void api_cb_ns_rpc_api_response(NS_RPC_RESPONSE *r){ jrnl_free_request(r->request); } USER *api_user(NS_RPC_REQUEST *r){ USER *u=user_of_connection(r->c); if(u){ user_init_alarm_objects(u); free(u->temp_project); free(u->temp_groups); u->temp_project=NULL; u->temp_groups=NULL; } return u; } USER_SESSION *api_session_con(NS_RPC_CONNECTION *c){ if(c && c->is_incoming){ return obj_payload(c->fn_data); }else{ return NULL; } } USER_SESSION *api_session(NS_RPC_REQUEST *r){ return api_session_con(r->c); } bool api_is_registered_user(NS_RPC_REQUEST *r){ USER *u=api_user(r); if(u && !u->anonymous){ return 1; }else{ ns_rpc_response_err(r,SERVER_ERROR_ACCESS_DENIED); return 0; } } USER *api_user_con(NS_RPC_CONNECTION *c){ USER *u=user_of_session(c->fn_data); if(u && !u->blocked){ user_init_alarm_objects(u); return u; }else{ return NULL; } } bool api_required(NS_RPC_REQUEST *r, char *params){ char *p; if(strcmp(params,"params")==0){ if(!r->params){ ns_rpc_response_err(r,NS_RPC_ERROR_PARAMS); return 0; } return 1; }else{ str_iter_bgn(params,",",p) if(!json_tok(r->params,p)){ ns_rpc_response_err(r,NS_RPC_ERROR_PARAMS); return 0; } str_iter_end return 1; } } bool api_is_user(NS_RPC_REQUEST *r){ if(api_user(r)){ return 1; }else{ ns_rpc_response_err(r,SERVER_ERROR_ACCESS_DENIED); return 0; } } bool api_is_admin_con(NS_RPC_CONNECTION *c){ USER *u=user_of_session(c->fn_data); if(u) return u->admin && !u->blocked; return 0; } bool api_is_user_con(NS_RPC_CONNECTION *c){ USER *u=user_of_session(c->fn_data); if(u) return !u->blocked; return 0; } bool api_is_admin(NS_RPC_REQUEST *r){ if(api_is_admin_con(r->c)){ return 1; }else{ ns_rpc_response_err(r,SERVER_ERROR_ADMIN_ACCESS_REQUIRED); return 0; } } void api_check_apikey(NS_RPC_REQUEST *r){ if(r->params && r->params->type==JSON_TYPE_OBJECT){ char *apikey=json_str(r->params,"pult_apikey"); if(user_check_apikey(apikey)==0){ USER *u=api_user(r); if(u && str_cmp(u->apikey,apikey)!=0){ USER_SESSION *us=api_session(r); user_tokout(us->login,us->token); user_unbind_session(r->c); u=NULL; } if(!u){ char *ip=r->c->tcp_host; USER_SESSION *us=user_apikey_session(apikey); if(us){ user_tokin(us->login,us->token,ip); user_bind_session(r->c,us); } } } } } bool api_is_write_access(NS_RPC_REQUEST *r){ USER *u=api_user(r); if(u && !u->blocked && !u->readonly){ return 1; }else{ ns_rpc_response_err(r,SERVER_ERROR_READONLY_ACCESS); return 0; } } bool api_is_editor_access(NS_RPC_REQUEST *r){ USER *u=api_user(r); if(u && !u->blocked && u->editor_access){ return 1; }else{ ns_rpc_response_err(r,SERVER_ERROR_ACCESS_DENIED); return 0; } } void api_cb_ns_rpc_api_request(NS_RPC_REQUEST *r){ api_check_apikey(r); jrnl_init_request(r); } //////////////////////////////////////////////////////////////////////////// void api_system_delete_logs(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"service")) return; char *service=json_str(r->params,"service"); jrnl(r,JRNL_SYSTEM_DELETE_LOGS,"object",service,NULL); char dir[PATH_MAX]; snprintf(dir,sizeof(dir),"%s/%s/logs",path_services_dir,service); errno=0; file_remove_dir_content(dir); ns_rpc_response(r,0); } void api_system_log_files(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"service")) return; char *service=json_str(r->params,"service"); char dir[PATH_MAX]; snprintf(dir,sizeof(dir),"%s/%s/logs",path_services_dir,service); JSTR s; jstr_init(&s,1024); jstr_opn_arr(&s); char *name; char *path; file_iter_sort_bgn(dir,FILE_TYPE_FILE,FILE_SORT_BY_NAME_ASC,name,path) jstr_opn_obj(&s); jstr_akey_ustr(&s,"name",0,name,0); jstr_akey_int(&s,"size",0,file_size(path)); jstr_cls_obj(&s); file_iter_sort_end jstr_cls_arr(&s); ns_rpc_response_raw_result(r,s.text,s.len); jstr_free(&s); } void api_system_config_data(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"service")) return; char p[PATH_MAX]; char *service=json_str(r->params,"service"); sprintf(p,"%s/%s/%s",path_services_dir,service,"config.cfg"); JSTR *s=&temp_str; jstr_reset(s); cfg_get_config_json(p,s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_system_config_schema(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"service")) return; char p[PATH_MAX]; char *service=json_str(r->params,"service"); sprintf(p,"%s/%s/%s",path_services_dir,service,"config.shema"); JSTR *s=&temp_str; jstr_reset(s); cfg_get_schema_json(p,s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_system_services(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(srv_supervisor->connected){ ns_rpc_request_proxy(srv_supervisor->c,"list",r); }else{ ns_rpc_response_err(r,SERVER_ERROR_SUPERVISOR_OFFLINE); } } void api_system_info(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; jstr_reset(&temp_str); jstr_opn_obj(&temp_str); jstr_akey_int(&temp_str,"version_number",0,VERSION_NUMBER); jstr_akey_astr(&temp_str,"version_date",0,VERSION_DATE,0); jstr_akey_int(&temp_str,"time_startup",0,stat_time_startup); jstr_akey_int(&temp_str,"time_stamp",0,time_ms()); jstr_akey_int(&temp_str,"time_zone",0,time_zone_offset()/60); jstr_akey_int(&temp_str,"total_vars",0,var_count); jstr_akey_int(&temp_str,"physical_vars",0,stat_physical_vars_cnt); jstr_akey_int(&temp_str,"trend_vars",0,stat_trend_vars_cnt); jstr_akey_int(&temp_str,"alarm_vars",0,stat_alarm_vars_cnt); jstr_akey_int(&temp_str,"license_vars",0,license_vars); jstr_akey_int(&temp_str,"signals",0,stat_core_changes); jstr_akey_dbl(&temp_str,"signals_per_second",0,stat_signals_per_second); jstr_akey_int(&temp_str,"gateway_count",0,stat_gateway_count); jstr_akey_int(&temp_str,"gateway_online",0,stat_gateway_online); jstr_akey_int(&temp_str,"gateway_incoming_traffic",0,stat_gateway_incoming_traffic); jstr_akey_int(&temp_str,"gateway_outgoing_traffic",0,stat_gateway_outgoing_traffic); jstr_akey_dbl(&temp_str,"gateway_incoming_traffic_per_second",0,stat_gateway_incoming_traffic_per_second); jstr_akey_dbl(&temp_str,"gateway_outgoing_traffic_per_second",0,stat_gateway_outgoing_traffic_per_second); jstr_akey_int(&temp_str,"service_count",0,stat_supervisor_app_count); jstr_akey_int(&temp_str,"service_runnings",0,stat_supervisor_app_runnings); jstr_akey_int(&temp_str,"service_errors",0,stat_supervisor_app_errors); jstr_akey_int(&temp_str,"space_free",0,stat_supervisor_space_free); jstr_akey_int(&temp_str,"space_total",0,stat_supervisor_space_total); jstr_akey_int(&temp_str,"mem_usage",0,stat_supervisor_mem_usage); jstr_akey_int(&temp_str,"mem_total",0,stat_supervisor_mem_total); jstr_akey_dbl(&temp_str,"cpu_usage",0,stat_supervisor_cpu_usage); jstr_akey_dbl(&temp_str,"cpu_usage_avg",0,stat_supervisor_cpu_usage_avg); jstr_akey_int(&temp_str,"connections",0,ns_stat_active_tcp_connections); jstr_akey_int(&temp_str,"accepts",0,ns_stat_tcp_accept_requests); jstr_akey_int(&temp_str,"subscriptions",0,ns_rpc_stat_subscriptions_count); jstr_cls_obj(&temp_str); ns_rpc_response_raw_result(r,temp_str.text,temp_str.len); } void api_system_time(NS_RPC_REQUEST *r){ jstr_reset(&temp_str); jstr_opn_obj(&temp_str); jstr_akey_int(&temp_str,"time",0,time_ms()); jstr_akey_int(&temp_str,"zone",0,time_zone_offset()/60); // in minutes jstr_akey_int(&temp_str,"os_time",0,time_ms_real()); jstr_akey_int(&temp_str,"os_zone",0,time_get_system_zone()/60); // in minutes jstr_cls_obj(&temp_str); ns_rpc_response_raw_result(r,temp_str.text,temp_str.len); } void api_system_set_time(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; uint32_t ts=json_int(r->params,"time"); int32_t tz=json_int(r->params,"zone"); // in minutes int64_t dt=(int64_t)ts*1000UL - time_ms(); time_correct(dt); time_set_zone(tz*60); double dts=(double)ts; jrnl(r,JRNL_SYSTEM_SET_TIME,"value",dts,NULL); prj_need_refresh(1); ns_rpc_response_true(r); } void api_system_reset_time(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; time_reset_correction(); jrnl(r,JRNL_SYSTEM_RESET_TIME,NULL); ns_rpc_response_true(r); } void api_system_ping(NS_RPC_REQUEST *r){ ns_rpc_response_true(r); } void api_system_ready(NS_RPC_REQUEST *r){ JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_int(s,"startup",0,stat_time_startup); jstr_akey_int(s,"version_number",0,VERSION_NUMBER); jstr_akey_astr(s,"version_date",0,VERSION_DATE,0); jstr_akey_int(s,"save_counter",0,save_counter); jstr_akey_int(s,"license_exceeded",0,stat_physical_vars_cnt > license_vars); jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_system_get_calendar(NS_RPC_REQUEST *r){ if(!param_calendar_public_access && !api_is_user(r)) return; char *calendar=file_read_text(param_calendar_file); uint32_t fm=file_modified(param_calendar_file); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_astr(s,"calendar",0,calendar,0); jstr_akey_int(s,"edited",0,fm); if(param_sync_calendar_enabled){ jstr_akey_int(s,"sync_last_time",0,sync_calendar_last_time); jstr_akey_int(s,"sync_last_error",0,sync_calendar_last_error); jstr_akey_ustr(s,"sync_url",0,param_sync_calendar_url,0); } jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); free(calendar); } void api_system_set_calendar(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"calendar")) return; int err=0; char *calendar=json_str(r->params,"calendar"); int len=json_size(r->params,"calendar"); if(len % CALENDAR_YEAR_SIZE != 0){ err=SERVER_ERROR_INVALID_FORMAT; goto exit; } int rc=file_write(param_calendar_file,calendar,-1); if(rc<0) err=errno; exit: ns_rpc_response(r,err); } void api_user_resetpass(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"login,password")) return; int err=0; char *login=json_str(r->params,"login"); char *password=json_str(r->params,"password"); bool changepass=json_int(r->params,"changepass"); if(strcmp(login,"anonymous")==0) err=SERVER_ERROR_OPERATION_FAILED; if(err) goto exit; err=user_reset_password(login,password,changepass); if(err) goto exit; user_close_sessions(login,NULL); exit: jrnl(r,JRNL_SECURITY_RESET_PASSWORD,"object",login,"error",err,NULL); ns_rpc_response(r,err); } void api_user_delete(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"login")) return; USER *u=api_user(r); int err=0; char *login=json_str(r->params,"login"); if(strcmp(login,"anonymous")==0) err=SERVER_ERROR_UNABLE_DELETE_SYSTEM_USER; if(err) goto exit; if(strcmp(login,param_demo_login)==0) err=SERVER_ERROR_UNABLE_DELETE_SYSTEM_USER; if(err) goto exit; if(strcmp(login,u->login)==0) err=SERVER_ERROR_DELETE_SELF; if(err) goto exit; user_close_sessions(login,NULL); err=user_delete(login); if(err) goto exit; exit: jrnl(r,JRNL_SECURITY_DELETE_USER,"object",login,"error",err,NULL); ns_rpc_response(r,err); } void api_user_notifications_watched(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; USER *u=api_user(r); char *params=str_f("{\"user\":\"%s\"}",u->login); ns_rpc_request_back(srv_db->c,"notification_watch",params,0,r); free(params); } void api_user_notifications(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; USER *u=api_user(r); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"user",0,u->login,0); if(json_exist(r->params,"watched")) jstr_akey_int(s,"watched",0,json_bool(r->params,"watched")); if(json_exist(r->params,"from")) jstr_akey_int(s,"from",0,json_int(r->params,"from")); jstr_cls_obj(s); ns_rpc_request_back(srv_db->c,"notification_read",s->text,s->len,r); } void api_user_login(NS_RPC_REQUEST *r){ if(!api_required(r,"login")) return; int err=0; char token[USER_TOKEN_SIZE]; char *login=json_param_str(r->params,"login"); char *password=json_param_str(r->params,"password"); char *browser=json_param_str(r->params,"browser"); int remember=json_param_int(r->params,"remember"); if(!browser) browser="Unknown"; if(!password) password=""; char *ip=r->c->tcp_host; err=user_login(login,password,remember,ip,browser,token); if(err) goto exit; exit: jrnl(r,JRNL_SECURITY_USER_LOGIN,"executor",login,"error",err,"data",str("{\"browser\":\"%s\"}",browser),NULL); if(err){ ns_rpc_response_err(r,err); char *msg=langf(&lng,"ntf_error_login",ip,browser); USER *u=user(login); ntf_send_regular_notification(u,NTF_TYPE_ERROR,msg,NULL); }else{ ns_rpc_response_str(r,token,0); char *msg=langf(&lng,"ntf_success_login",ip,browser); char *tok=user_gettok(token); USER *u=user(login); ntf_send_regular_notification(u,NTF_TYPE_LOGIN,msg,tok); } } void api_user_tokin(NS_RPC_REQUEST *r){ if(!api_required(r,"login,token")) return; int err=0; char *login=json_param_str(r->params,"login"); char *token=json_param_str(r->params,"token"); char *ip=r->c->tcp_host; err=user_tokin(login,token,ip); if(err) goto exit; USER_SESSION *us=user_session(login,token); user_bind_session(r->c,us); exit: ns_rpc_response(r,err); } void api_user_get(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; char *login=json_str(r->params,"login"); USER *u=NULL; if(login){ if(!api_is_admin(r)) return; u=user(login); }else{ u=api_user(r); } if(u){ JSTR *s=&temp_str; jstr_reset(s); user_get_json(u,s); ns_rpc_response_raw_result(r,s->text,s->len); }else{ ns_rpc_response_err(r,SERVER_ERROR_USER_NOT_FOUND); } } void api_user_active(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER_SESSION *us=api_session(r); user_active(us->login,us->token); ns_rpc_response(r,0); } void api_user_close_session(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"tok")) return; int err=0; USER *u=api_user(r); char *login=json_strd(r->params,"login"); char *tok=json_str(r->params,"tok"); if(login){ if(!api_is_admin(r)) return; }else{ login=strdup(u->login); } if(!user_exists(login)){ err=SERVER_ERROR_USER_NOT_FOUND; goto exit; } char *token=user_gettoken(login,tok); if(!token){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } user_close_session(login,token); exit: jrnl(r,JRNL_SECURITY_CLOSE_SESSION,"object",login,NULL); ns_rpc_response(r,err); free(login); } void api_user_sessions(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; char *login=json_str(r->params,"login"); USER *u=api_user(r); if(login){ if(!str_equal(login,u->login) && !api_is_admin(r)) return; }else{ login=u->login; } if(user_exists(login)){ JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); OBJ *ss=obj(user_get_sessions_path(login)); USER_SESSION *us; obj_iter_type_bgn(ss,us,"session") user_session_get_json(us,s); obj_iter_type_end jstr_cls_arr(s); ns_rpc_response_raw_result(r,s->text,s->len); }else{ ns_rpc_response_err(r,SERVER_ERROR_USER_NOT_FOUND); } } void api_user_changepass(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"cur_password,new_password")) return; USER_SESSION *us=api_session(r); char *login=strdup(us->login); char *token=strdup(us->token); char *cur_password=json_str(r->params,"cur_password"); char *new_password=json_str(r->params,"new_password"); int err=user_change_password(login,cur_password,new_password,0); if(err) goto exit; user_close_sessions(login,token); exit: jrnl(r,JRNL_SECURITY_CHANGE_PASSWORD,"error",err,NULL); ns_rpc_response(r,err); free(login); free(token); } void api_user_save_profile(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_required(r,"login")) return; if(!api_is_write_access(r)) return; int err=0; USER *u=api_user(r); free(u->home_page); free(u->home_project); free(u->home_url); free(u->icon); free(u->name); free(u->phone); free(u->email); free(u->language); u->home_page=json_strd(r->params,"home_page"); u->home_project=json_strd(r->params,"home_project"); u->home_url=json_strd(r->params,"home_url"); u->icon=json_strd(r->params,"icon"); u->name=json_strd(r->params,"name"); u->language=json_strd(r->params,"language"); u->phone=json_strd(r->params,"phone"); u->email=json_strd(r->params,"email"); u->receive_email=json_bool(r->params,"receive_email"); u->receive_telegram=json_bool(r->params,"receive_telegram"); u->receive_sms=json_bool(r->params,"receive_sms"); err=user_save_user(u->o); exit: jrnl(r,JRNL_SECURITY_EDIT_PROFILE,"error",err,NULL); ns_rpc_response(r,err); } void api_user_list(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); USER *u; obj_iter_type_bgn(obj("/users"),u,"user") user_get_json(u,s); obj_iter_type_end jstr_cls_arr(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_user_save(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"cur_login,new_login")) return; int block_event=0; int err=0; USER *u; char *cur_login=json_str(r->params,"cur_login"); char *new_login=json_str(r->params,"new_login"); bool blocked=json_bool(r->params,"blocked"); bool admin=json_bool(r->params,"admin"); bool anonymous=(strcmp(cur_login,"anonymous")==0); bool editor_access=json_bool(r->params,"editor_access"); if(anonymous){ if(admin || editor_access || (strcmp(new_login,cur_login)!=0)){ err=SERVER_ERROR_OPERATION_FAILED; if(err) goto exit; } } if(strcmp(cur_login,new_login)!=0){ if(user_exists(new_login)){ err=SERVER_ERROR_USER_EXISTS; goto exit; } } u=user(cur_login); if(!u) err=SERVER_ERROR_USER_NOT_FOUND; if(err) goto exit; if(!u->blocked && blocked){ block_event=JRNL_SECURITY_BLOCK_USER; }else if(u->blocked && !blocked){ block_event=JRNL_SECURITY_UNBLOCK_USER; } free(u->home_page); free(u->home_project); free(u->home_url); free(u->icon); free(u->name); free(u->department); free(u->apikey); free(u->position); free(u->language); free(u->info); free(u->phone); free(u->email); u->home_page=json_strd(r->params,"home_page"); u->home_project=json_strd(r->params,"home_project"); u->home_url=json_strd(r->params,"home_url"); u->icon=json_strd(r->params,"icon"); u->name=json_strd(r->params,"name"); u->language=json_strd(r->params,"language"); u->department=json_strd(r->params,"department"); u->apikey=json_strd(r->params,"apikey"); u->position=json_strd(r->params,"position"); u->info=json_strd(r->params,"info"); u->phone=json_strd(r->params,"phone"); u->email=json_strd(r->params,"email"); u->admin=json_bool(r->params,"admin"); u->blocked=json_bool(r->params,"blocked"); u->readonly=json_bool(r->params,"readonly"); u->changepass=json_bool(r->params,"changepass"); u->receive_email=json_bool(r->params,"receive_email"); u->receive_telegram=json_bool(r->params,"receive_telegram"); u->receive_sms=json_bool(r->params,"receive_sms"); u->kiosk_mode=json_bool(r->params,"kiosk_mode"); u->editor_access=json_bool(r->params,"editor_access"); err=user_save_user(u->o); if(strcmp(cur_login,new_login)!=0){ USER_SESSION *us=api_session(r); user_close_sessions(cur_login,us->token); err=user_rename(cur_login,new_login); if(strcmp(us->login,new_login)==0){ free(r->c->fn_data); r->c->fn_data=strdup(obj_path(us->o)); } if(err) goto exit; } exit: jrnl(r,JRNL_SECURITY_EDIT_USER,"object",new_login,"error",err,NULL); if(!err){ if(block_event==JRNL_SECURITY_BLOCK_USER){ USER_SESSION *us=api_session(r); jrnl(NULL,JRNL_SECURITY_BLOCK_USER,"ip",us->ip,"executor",us->login,"object",new_login,"error",err,NULL); user_close_sessions(cur_login,NULL); user_close_sessions(new_login,NULL); }else if(block_event==JRNL_SECURITY_UNBLOCK_USER){ USER_SESSION *us=api_session(r); jrnl(NULL,JRNL_SECURITY_UNBLOCK_USER,"ip",us->ip,"executor",us->login,"object",new_login,"error",err,NULL); } } ns_rpc_response(r,err); } void api_user_create(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"login,password")) return; int err=0; char *login=json_str(r->params,"login"); char *password=json_str(r->params,"password"); if(strcmp(login,"anonymous")==0) err=SERVER_ERROR_OPERATION_FAILED; if(err) goto exit; err=user_create(login); if(err) goto exit; err=user_change_password(login,NULL,password,0); if(err) goto exit; USER *u=user(login); u->admin=json_bool(r->params,"admin"); u->blocked=json_bool(r->params,"blocked"); u->readonly=json_bool(r->params,"readonly"); u->changepass=json_bool(r->params,"changepass"); u->home_page=json_strd(r->params,"home_page"); u->home_project=json_strd(r->params,"home_project"); u->home_url=json_strd(r->params,"home_url"); u->icon=json_strd(r->params,"icon"); u->name=json_strd(r->params,"name"); u->language=json_strd(r->params,"language"); u->department=json_strd(r->params,"department"); u->apikey=json_strd(r->params,"apikey"); u->position=json_strd(r->params,"position"); u->info=json_strd(r->params,"info"); u->phone=json_strd(r->params,"phone"); u->email=json_strd(r->params,"email"); u->receive_email=json_bool(r->params,"receive_email"); u->receive_telegram=json_bool(r->params,"receive_telegram"); u->receive_sms=json_bool(r->params,"receive_sms"); u->kiosk_mode=json_bool(r->params,"kiosk_mode"); u->editor_access=json_bool(r->params,"editor_access"); err=user_save_user(u->o); exit: jrnl(r,JRNL_SECURITY_CREATE_USER,"object",login,"error",err,NULL); ns_rpc_response(r,err); } void api_user_block(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"login")) return; int err=0; char *login=json_str(r->params,"login"); USER *u=api_user(r); if(strcmp(login,u->login)==0) err=SERVER_ERROR_BLOCK_SELF; if(err) goto exit; err=user_block(login); if(err) goto exit; user_close_sessions(login,NULL); exit: jrnl(r,JRNL_SECURITY_BLOCK_USER,"object",login,"error",err,NULL); ns_rpc_response(r,err); } void api_user_unblock(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"login")) return; int err=0; char *login=json_str(r->params,"login"); err=user_unblock(login); if(err) goto exit; exit: jrnl(r,JRNL_SECURITY_UNBLOCK_USER,"object",login,"error",err,NULL); ns_rpc_response(r,err); } void api_user_logout(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; int err=0; USER_SESSION *us=api_session(r); char *login=strdup(us->login); char *token=strdup(us->token); char *browser=strdup(us->browser); err=user_logout(login,token); if(err) goto exit; exit: jrnl(r,JRNL_SECURITY_USER_LOGOUT,"executor",login,"error",err,"data",str("{\"browser\":\"%s\"}",browser),NULL); ns_rpc_response(r,err); free(login); free(browser); free(token); } void api_fdb_prototype_nodes(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } char *sp=prj_short_path(path); char *project_path=prj_path(path); OBJ *objects=obj(fdb_children_path(project_path,"nodes")); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); OBJ *o; obj_iter_all_children_bgn(objects,o) JSON *p=obj_doc_json(o,"@prop.json"); if(p){ JSON *t=json_tok(p,"prototype"); if(t && str_equal(json_tos(t),sp)){ if(acs(u,o->fo->path,ACS_TYPE_VIEW,1)){ //obj_get_object_json(s,o,NULL,0,0,0,0,NULL,0,0); jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,o->fo->path,0); jstr_akey_ustr(s,"type",0,o->type,0); jstr_akey_ustr(s,"icon",0,o->icon,0); jstr_akey_int(s,"inactive",0,o->inactive); jstr_cls_obj(s); } } } obj_iter_all_children_end jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_mimic_objects(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } char *sp=prj_short_path(path); char *project_path=prj_path(path); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); { OBJ *objects=obj(fdb_children_path(project_path,"screens")); OBJ *o; obj_iter_all_children_bgn(objects,o) JSON *p=obj_doc_json(o,"@prop.json"); if(p){ { JSON *t=json_tok(p,"desktop_mimic"); if(t && str_equal(json_tos(t),sp)){ if(acs(u,o->fo->path,ACS_TYPE_VIEW,1)){ jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,o->fo->path,0); jstr_akey_ustr(s,"type",0,o->type,0); jstr_akey_ustr(s,"icon",0,o->icon,0); jstr_akey_int(s,"inactive",0,o->inactive); jstr_cls_obj(s); } } } { JSON *t=json_tok(p,"mobile_mimic"); if(t && str_equal(json_tos(t),sp)){ if(acs(u,o->fo->path,ACS_TYPE_VIEW,1)){ jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,o->fo->path,0); jstr_akey_ustr(s,"type",0,o->type,0); jstr_akey_ustr(s,"icon",0,o->icon,0); jstr_akey_int(s,"inactive",0,o->inactive); jstr_cls_obj(s); } } } } obj_iter_all_children_end } { OBJ *objects=obj(fdb_children_path(project_path,"prototypes")); OBJ *o; obj_iter_all_children_bgn(objects,o) JSON *p=obj_doc_json(o,"@prop.json"); if(p){ { JSON *t=json_tok(p,"desktop_mimic"); if(t && str_equal(json_tos(t),sp)){ if(acs(u,o->fo->path,ACS_TYPE_VIEW,1)){ jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,o->fo->path,0); jstr_akey_ustr(s,"type",0,o->type,0); jstr_akey_ustr(s,"icon",0,o->icon,0); jstr_akey_int(s,"inactive",0,o->inactive); jstr_cls_obj(s); } } } { JSON *t=json_tok(p,"mobile_mimic"); if(t && str_equal(json_tos(t),sp)){ if(acs(u,o->fo->path,ACS_TYPE_VIEW,1)){ jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,o->fo->path,0); jstr_akey_ustr(s,"type",0,o->type,0); jstr_akey_ustr(s,"icon",0,o->icon,0); jstr_akey_int(s,"inactive",0,o->inactive); jstr_cls_obj(s); } } } } obj_iter_all_children_end } jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_bundle(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); JSON *ext=json_tok(r->params,"ext"); if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); OBJ *parent=obj(path); if(parent->fo->children){ OBJ *o; obj_iter_all_children_bgn(parent,o) char *path=obj_path(o); bool ok=1; if(ext && ok){ char *name=file_name(path); char *oe=file_ext(name); ok=0; //printf("\n\n%s [%s]\n\n",path,oe); if(ext->type==JSON_TYPE_STRING){ ok=str_cmp(oe,json_tos(ext))==0; }else if(ext->type==JSON_TYPE_ARRAY){ int i; char *e; json_iter_array_str_bgn(ext,i,e) ok=str_cmp(oe,e)==0; if(ok) break; json_iter_array_str_end } } if(ok){ jstr_opn_obj(s); jstr_akey_ustr(s,"file",0,path,0); if(acs(u,path,ACS_TYPE_VIEW,1)){ void *data; int64_t size; FDB_OBJ *o=fdb_get_obj(&fdb,path); if(o){ int err=fdb_read_doc(&fdb,o,"@content",&data,&size); if(err){ jstr_akey_int(s,"error",0,err); }else{ jstr_akey_ustr(s,"data",0,data,size); } } }else{ jstr_akey_int(s,"error",0,SERVER_ERROR_ACCESS_DENIED); } jstr_cls_obj(s); } obj_iter_all_children_end }else{ void *data; int64_t size; FDB_OBJ *o=fdb_get_obj(&fdb,path); if(o){ jstr_opn_obj(s); fdb_read_doc(&fdb,o,"@content",&data,&size); jstr_akey_ustr(s,"file",0,path,0); jstr_akey_ustr(s,"data",0,data,size); jstr_cls_obj(s); } } jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_paths(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); JSON *ext=json_tok(r->params,"ext"); JSON *type=json_tok(r->params,"type"); bool dirs=json_bool(r->params,"dirs"); bool root=json_bool(r->params,"root"); if(!obj_exists(path)){ //printf("\n\n%s\n\n",path); err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); if(root){ int len=strlen(path); if(path[len-1]=='/'){ jstr_ustr(s,path,len-1); }else{ jstr_ustr(s,path,len); } } OBJ *parent=obj(path); OBJ *o; obj_iter_all_children_bgn(parent,o) char *path=obj_path(o); bool ok=1; if(ext && ok){ char *name=file_name(path); char *oe=file_ext(name); ok=0; //printf("\n\n%s [%s]\n\n",path,oe); if(dirs && !oe[0]){ ok=1; }else if(ext->type==JSON_TYPE_STRING){ ok=str_cmp(oe,json_tos(ext))==0; }else if(ext->type==JSON_TYPE_ARRAY){ int i; char *e; json_iter_array_str_bgn(ext,i,e) ok=str_cmp(oe,e)==0; if(ok) break; json_iter_array_str_end } } if(type && ok){ ok=0; if(type->type==JSON_TYPE_STRING){ ok=str_cmp(o->type,json_tos(type))==0; }else if(type->type==JSON_TYPE_ARRAY){ int i; char *t; json_iter_array_str_bgn(type,i,t) ok=str_cmp(o->type,t)==0; if(ok) break; json_iter_array_str_end } } if(ok && acs(u,path,ACS_TYPE_VIEW,1)){ jstr_ustr(s,path,0); } obj_iter_all_children_end jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_search(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); char *path=json_str(r->params,"path"); char *search=json_str(r->params,"search"); if(!path) path="/projects"; char *docs[]={"@prop.json",NULL}; int count=0; int more=0; int max=1000; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey(s,"list",0); jstr_opn_arr(s); if(search){ int sc=str_list_count(search," "); char **ss=malloc(sc*sizeof(char*)); int i=0; char *si; str_list_iter_bgn(search," ",si) ss[i++] = (char*) utf8_to_lower((unsigned char*)si); str_list_iter_end OBJ *o; obj_iter_all_children_bgn(obj(path),o) OBJ_TYPE *t=obj_schema_type(o->type); if(!o->hidden && !o->inactive && t->interface){ char *path=obj_path(o); bool ok=1; if(ok && acs(u,path,ACS_TYPE_VIEW,1)){ JSON *prop=obj_doc_json(o,"@prop.json"); char *name=json_str(prop,"alias"); if(!name) name=obj_title(o); char *lname = (char*) utf8_to_lower((unsigned char*)name); ok=1; for(int i=0; i=max){ more=max; free(lname); break; } obj_get_object_json(s,o,docs,0,1,0,0,u,0,0,1); count++; } free(lname); } } obj_iter_all_children_end for(int i=0; itext,s->len); } void api_fdb_list(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); JSON *inactive=json_tok(r->params,"inactive"); JSON *docs=json_tok(r->params,"docs"); int children=json_int(r->params,"children"); int access=json_int(r->params,"access"); bool interface=json_bool(r->params,"interface"); int inact = inactive ? json_tob(inactive) : -1; if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } char **dd=NULL; if(docs){ if(docs->type==JSON_TYPE_ARRAY){ dd=calloc(docs->count+1,sizeof(char*)); int i; char *d; json_iter_array_str_bgn(docs,i,d) dd[i]=d; json_iter_array_str_end }else if(docs->type==JSON_TYPE_STRING){ dd=calloc(2,sizeof(char*)); dd[0]=json_tos(docs); } } int parent_access=0; if(access & ACS_TYPE_VIEW) parent_access+=acs(u,path,ACS_TYPE_VIEW,1); if(access & ACS_TYPE_EDIT) parent_access+=acs(u,path,ACS_TYPE_EDIT,1); if(access & ACS_TYPE_EXEC) parent_access+=acs(u,path,ACS_TYPE_EXEC,1); JSTR *s=&temp_str; jstr_reset(s); obj_get_list_json(s,path,dd,inact,interface,children,u,access,parent_access); free(dd); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_access(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; int ret=0; char *path=json_str(r->params,"path"); int access=json_int_def(r->params,"access",ACS_TYPE_VIEW); OBJ *o=obj(path); if(!o){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } ret=acs(u,path,access,1); exit: if(err){ ns_rpc_response_err(r,err); }else{ ns_rpc_response_bool(r,ret); } } void api_fdb_load(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); JSON *docs=json_tok(r->params,"docs"); bool parent=json_bool(r->params,"parent"); int children=json_int(r->params,"children"); int access=json_int(r->params,"access"); bool interface=json_bool(r->params,"interface"); JSON *inactive=json_tok(r->params,"inactive"); int inact = inactive ? json_tob(inactive) : -1; if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } int ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } char **dd=NULL; if(docs){ if(docs->type==JSON_TYPE_ARRAY){ dd=calloc(docs->count+1,sizeof(char*)); int i; char *d; json_iter_array_str_bgn(docs,i,d) dd[i]=d; json_iter_array_str_end }else if(docs->type==JSON_TYPE_STRING){ dd=calloc(2,sizeof(char*)); dd[0]=json_tos(docs); } } char *parent_path=fdb_parent_path(path); int parent_access=0; if(access & ACS_TYPE_VIEW) parent_access+=acs(u,parent_path,ACS_TYPE_VIEW,1); if(access & ACS_TYPE_EDIT) parent_access+=acs(u,parent_path,ACS_TYPE_EDIT,1); if(access & ACS_TYPE_EXEC) parent_access+=acs(u,parent_path,ACS_TYPE_EXEC,1); JSTR *s=&temp_str; jstr_reset(s); obj_get_object_json(s,obj(path),dd,inact,interface,parent,children,u,access,parent_access,0); free(dd); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_save(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } bool ok=acs(u,path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); err=obj_validate(OBJ_METHOD_WRITE,o->fo->path,r->params); if(err) goto exit; char *k; JSON *t; json_iter_object_bgn(r->params,k,t) if(k[0]=='@'){ char *format=json_str(t,"format"); JSON *data=json_tok(t,"data"); if(str_cmp(format,"json")==0){ int len; char *text=json_stringify_buf(&temp_json_buffer,data,&len); err=obj_write_with_check_access(o,k,text,len,u,&err_desc); if(err) goto exit; }else if(str_cmp(format,"text")==0){ char *text=json_tos(data); int len=json_tol(data); err=obj_write_with_check_access(o,k,text,len,u,&err_desc); if(err) goto exit; }else if(str_cmp(format,"base64")==0){ char *text=json_tos(data); int size=json_tol(data); int len; void *bytes=str_base64_decode((unsigned char*)text,size,&len); err=obj_write_with_check_access(o,k,bytes,len,u,&err_desc); free(bytes); } } json_iter_object_end exit: { char *project=prj_name(path); char *object=prj_pseudo_path(path,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_true(r); } } void api_fdb_save_doc(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path,file,format")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *file=json_str(r->params,"file"); char *format=json_str(r->params,"format"); char *data=json_str(r->params,"data"); int size=json_size(r->params,"data"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } bool ok=acs(u,path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); if(strcmp(format,"base64")!=0) err=SERVER_ERROR_INVALID_FORMAT; if(err) goto exit; int len; void *bytes=str_base64_decode((unsigned char*)data,size,&len); err=obj_write_with_check_access(o,file,bytes,len,u,&err_desc); free(bytes); exit: { char *project=prj_name(path); char *object=prj_pseudo_path(path,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_true(r); } } void api_fdb_load_doc(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path,file")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *file=json_str(r->params,"file"); char *format=json_str_def(r->params,"format","base64"); if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } bool ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); void *data; int64_t size; err=fdb_read_doc(&fdb,o->fo,file,&data,&size); if(err) goto exit; if(strcmp(format,"base64")==0){ jstr_akey_astr(s,"format",0,"base64",0); jstr_akey_base64(s,"data",0,data,size); }else if(strcmp(format,"json")==0){ jstr_akey_astr(s,"format",0,"json",0); jstr_akey_raw(s,"data",0,data,size); } jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); } } void api_fdb_list_doc(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } bool ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); char *doc; khash_iter_bgn(o->fo->docs,doc) jstr_ustr(s,doc,0); khash_iter_end jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_fdb_delete(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } bool ok=acs(u,path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } err=obj_validate(OBJ_METHOD_DELETE,path,r->params); if(err) goto exit; err=fdb_delete_obj(&fdb,path); exit: { char *project=prj_name(path); char *object=prj_pseudo_path(path,1); jrnl(r,JRNL_PROJECT_DELETE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_true(r); } } void api_fdb_move(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path,dest")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *dest=json_str(r->params,"dest"); bool strict=json_bool(r->params,"strict"); // return error if dest exists if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } { bool ok=acs(u,path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } } { char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } } { char *parent_path=fdb_parent_path(dest); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } } if(obj_exists(dest)){ if(strict){ err=SERVER_ERROR_OBJECT_EXISTS; goto exit; }else{ dest=fdb_next_name(&fdb,dest); } } err=obj_validate(OBJ_METHOD_DELETE,path,r->params); if(err) goto exit; err=obj_validate(OBJ_METHOD_CREATE,dest,r->params); if(err) goto exit; err=fdb_move_obj(&fdb,path,dest); if(err) goto exit; exit: { char *project=prj_name(dest); char *object=prj_pseudo_path(dest,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,dest,0); } } void api_fdb_upload(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; bool created=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *data=json_str(r->params,"data"); int size=json_size(r->params,"data"); bool folder=json_bool(r->params,"folder"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } //printf("\n\n%s %u\n\n",path,folder); if(!obj_exists(path)){ if(folder){ err=fdb_create_dir(&fdb,path); }else{ err=fdb_create_file(&fdb,path); } if(err) goto exit; created=1; } OBJ *o=obj(path); if(!folder){ int len=0; void *bytes=str_base64_decode((unsigned char*)data,size,&len); if(len){ err=obj_write(o,"@content",bytes,len); }else{ char *f=fdb_abs_path(&fdb,path); int rc=file_create(f); if(rc!=0) err=errno; } free(bytes); } exit: { char *project=prj_name(path); char *object=prj_pseudo_path(path,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ if(created){ ns_rpc_response_true(r); }else{ ns_rpc_response_false(r); } } } void api_fdb_create(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(obj_exists(path)){ err=SERVER_ERROR_OBJECT_ALREADY_EXISTS; goto exit; } char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } err=obj_validate(OBJ_METHOD_CREATE,path,r->params); if(err) goto exit; err=obj_create(path); if(err) goto exit; exit: { char *project=prj_name(path); char *object=prj_pseudo_path(path,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,path,0); } } void api_fdb_create_next(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *next=NULL; if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } next=fdb_next_name(&fdb,path); err=obj_validate(OBJ_METHOD_CREATE,next,r->params); if(err) goto exit; err=obj_create(next); if(err) goto exit; exit: { char *p=next ? next : path; char *project=prj_name(p); char *object=prj_pseudo_path(p,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,next,0); } } void api_fdb_nextname(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *next=NULL; char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } next=fdb_next_name(&fdb,path); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,next,0); } } void api_fdb_clone(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *next=NULL; if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } char *parent_path=fdb_parent_path(path); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } next=fdb_next_name(&fdb,path); err=obj_validate(OBJ_METHOD_CREATE,next,r->params); if(err) goto exit; err=fdb_copy_obj(&fdb,path,next); if(err) goto exit; exit: { char *p=next ? next : path; char *project=prj_name(p); char *object=prj_pseudo_path(p,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,next,0); } } void api_fdb_copy(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path,dest")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *dest=json_str(r->params,"dest"); bool strict=json_bool(r->params,"strict"); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } char *parent_path=fdb_parent_path(dest); bool ok=acs(u,parent_path,ACS_TYPE_EDIT,1); if(!ok){ OBJ *ao=obj_access(parent_path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } if(obj_exists(dest)){ if(strict){ err=SERVER_ERROR_OBJECT_EXISTS; goto exit; }else{ dest=fdb_next_name(&fdb,dest); } } err=obj_validate(OBJ_METHOD_CREATE,dest,r->params); if(err) goto exit; err=fdb_copy_obj(&fdb,path,dest); if(err) goto exit; exit: { char *project=prj_name(dest); char *object=prj_pseudo_path(dest,1); jrnl(r,JRNL_PROJECT_WRITE_DATA,"project",project,"object",object,"error",err,NULL); } if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,dest,0); } } void api_system_groups(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); // project path OBJ *p=obj_project(path); if(!p){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } char *ggpath=fdb_children_path(p->fo->path,"groups"); OBJ *gg=obj(ggpath); if(!gg){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=ggpath; goto exit; } bool ok=acs(u,obj_path(gg),ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); USER_GROUP *ug; obj_iter_type_bgn(gg,ug,"group") jstr_ustr(s,ug->name,0); obj_iter_type_end jstr_cls_arr(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_system_access(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; JSON *inherit_view=NULL; JSON *inherit_edit=NULL; JSON *inherit_exec=NULL; char *inherit_view_mode=NULL; char *inherit_edit_mode=NULL; char *inherit_exec_mode=NULL; char *inherit_view_groups=NULL; char *inherit_edit_groups=NULL; char *inherit_exec_groups=NULL; char *explicit_access=NULL; char *path=json_str(r->params,"path"); char *parent=strdup(fdb_parent_path(path)); bool ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); OBJ *inherit_view_ao=obj_access(parent,ACS_TYPE_VIEW); OBJ *inherit_edit_ao=obj_access(parent,ACS_TYPE_EDIT); OBJ *inherit_exec_ao=obj_access(parent,ACS_TYPE_EXEC); char *inherit_view_path=obj_path(inherit_view_ao); char *inherit_edit_path=obj_path(inherit_edit_ao); char *inherit_exec_path=obj_path(inherit_exec_ao); JSON *a=obj_doc_json(o,"@access.json"); explicit_access=json_stringify_buf(&temp_json_buffer,a,NULL); if(inherit_view_ao){ JSON *a=obj_doc_json(inherit_view_ao,"@access.json"); inherit_view=json_tok(a,"view"); inherit_view_mode=json_str_def(inherit_view,"mode","allow"); inherit_view_groups=json_param_stringify(inherit_view,"groups"); if(!inherit_view_groups) inherit_view_groups=strdup("[]"); } if(inherit_exec_ao){ JSON *a=obj_doc_json(inherit_exec_ao,"@access.json"); inherit_exec=json_tok(a,"exec"); inherit_exec_mode=json_str_def(inherit_exec,"mode","allow"); inherit_exec_groups=json_param_stringify(inherit_exec,"groups"); if(!inherit_exec_groups) inherit_exec_groups=strdup("[]"); } if(inherit_edit_ao){ JSON *a=obj_doc_json(inherit_edit_ao,"@access.json"); inherit_edit=json_tok(a,"edit"); inherit_edit_mode=json_str_def(inherit_edit,"mode","allow"); inherit_edit_groups=json_param_stringify(inherit_edit,"groups"); if(!inherit_edit_groups) inherit_edit_groups=strdup("[]"); } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey(s,"inherit",0); jstr_opn_obj(s); jstr_akey(s,"view",0); jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,inherit_view_path,0); jstr_akey_ustr(s,"mode",0,inherit_view_mode,0); jstr_akey_raw(s,"groups",0,inherit_view_groups,0); jstr_cls_obj(s); jstr_akey(s,"exec",0); jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,inherit_exec_path,0); jstr_akey_ustr(s,"mode",0,inherit_exec_mode,0); jstr_akey_raw(s,"groups",0,inherit_exec_groups,0); jstr_cls_obj(s); jstr_akey(s,"edit",0); jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,inherit_edit_path,0); jstr_akey_ustr(s,"mode",0,inherit_edit_mode,0); jstr_akey_raw(s,"groups",0,inherit_edit_groups,0); jstr_cls_obj(s); jstr_cls_obj(s); jstr_akey_raw(s,"explicit",0,explicit_access,0); jstr_cls_obj(s); exit: free(parent); free(inherit_view_groups); free(inherit_edit_groups); free(inherit_exec_groups); if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_system_html_files(NS_RPC_REQUEST *r){ if(!api_required(r,"folder")) return; char *folder=json_str(r->params,"folder"); char *dir=file_subpath(param_html_dir,folder); if(dir){ JSTR s; jstr_init(&s,256); jstr_opn_arr(&s); char *name; char *path; file_iter_bgn(dir,FILE_TYPE_ANY,name,path) bool isdir=file_isdir(path); jstr_opn_obj(&s); jstr_akey_ustr(&s,"name",0,name,0); if(!isdir) jstr_akey_int(&s,"size",0,file_size(path)); jstr_akey_astr(&s,"type",0,isdir?"dir":"file",0); jstr_cls_obj(&s); file_iter_end jstr_cls_arr(&s); ns_rpc_response_raw_result(r,s.text,s.len); jstr_free(&s); free(dir); }else{ ns_rpc_response_err(r,SERVER_ERROR_OPERATION_FAILED); } } void api_system_set_config(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"config")) return; if(!api_is_write_access(r)) return; JSON *config=json_tok(r->params,"config"); char *rp=json_stringify_buf(&temp_json_buffer,config,NULL); jrnl(r,JRNL_SYSTEM_SET_CONFIG,"data",rp,NULL); char *service; JSON *params; json_iter_object_bgn(config,service,params) char *config=str("%s/%s/config.cfg",path_services_dir,service); CFG *cfg=cfg_open(config,NULL); if(cfg){ int n=0; char *param; char *value; json_iter_object_str_bgn(params,param,value) if(cfg_exist(cfg,param)){ char *old=cfg_str(cfg,param,NULL); if(str_cmp(old,value)!=0){ log(r->c->id, "- %s=%s",param,value); cfg_set_str(cfg,param,value); n++; } } json_iter_object_str_end if(n) cfg_save(cfg); cfg_free(cfg); // restart_service(service); // service will be restarted by supervisor on config update } json_iter_object_end ns_rpc_response_true(r); } void api_system_reset_config(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"service")) return; if(!api_is_write_access(r)) return; char *service=json_str(r->params,"service"); char *file=str("%s/%s/config.cfg",path_services_dir,service); errno=0; file_remove(file); if(file_exists(file)){ ns_rpc_response(r,errno); }else{ ns_rpc_response_true(r); } } void api_system_check_config(NS_RPC_REQUEST *r){ if(!api_required(r,"service")) return; if(!api_is_admin(r)) return; char *service=json_str(r->params,"service"); char *file=str("%s/%s/config.cfg",path_services_dir,service); if(file_exists(file)){ ns_rpc_response_true(r); }else{ ns_rpc_response_false(r); } } void api_ddos_forget(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"ip")) return; if(!api_is_write_access(r)) return; JSON *ips=json_tok(r->params,"ip"); char *ip_str=json_stringify_buf(&temp_json_buffer,ips,NULL); jrnl(r,JRNL_SYSTEM_DDOS_FORGET,"data",ip_str,NULL); char *ip; int i; json_iter_array_str_bgn(ips,i,ip) ns_ddos_forget(ip); json_iter_array_str_end ns_rpc_response_true(r); ns_ddos_routine(1); } void api_ddos_block(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"ip")) return; if(!api_is_write_access(r)) return; JSON *ips=json_tok(r->params,"ip"); char *ip_str=json_stringify_buf(&temp_json_buffer,ips,NULL); jrnl(r,JRNL_SECURITY_BLOCK_IP,"data",ip_str,NULL); char *ip; int i; json_iter_array_str_bgn(ips,i,ip) ns_ddos_set_blocked(ip,1); json_iter_array_str_end ns_rpc_response_true(r); } void api_ddos_unblock(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_required(r,"ip")) return; if(!api_is_write_access(r)) return; JSON *ips=json_tok(r->params,"ip"); char *ip_str=json_stringify_buf(&temp_json_buffer,ips,NULL); jrnl(r,JRNL_SECURITY_UNBLOCK_IP,"data",ip_str,NULL); char *ip; int i; json_iter_array_str_bgn(ips,i,ip) ns_ddos_set_blocked(ip,0); json_iter_array_str_end ns_rpc_response_true(r); } void api_schedule_list(NS_RPC_REQUEST *r){ // if(!api_is_user(r)) return; // if(!api_required(r,"path")) return; // USER *u=api_user(r); // int err=0; // char *path=json_str(r->params,"path"); // OBJ *p=obj(path); // if(!p){ // err=SERVER_ERROR_OBJECT_NOT_FOUND; // goto exit; // } // if(!acs(u,path,ACS_TYPE_VIEW,1)){ // err=SERVER_ERROR_ACCESS_DENIED; // goto exit; // } // JSTR *s=&temp_str; // jstr_reset(s); // jstr_opn_arr(s); // OBJ *ch; // obj_iter_bgn(p,ch,NULL) // printf("\n\n%s\n\n",ch->fo->name); // JSON *content=obj_doc_json(ch,"@content.json"); // jstr_opn_obj(s); // jstr_akey_ustr(s,"name",ch->fo->name); // jstr_cls_obj(s); // obj_iter_end // jstr_cls_arr(s); // exit: // if(err){ // ns_rpc_response_err(r,err); // }else{ // ns_rpc_response_raw_result(r,s->text,s->len); // } } void api_editor_group_users(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_required(r,"project")) return; int err=0; USER *user=api_user(r); if(!user->editor_access){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } char *project=json_str(r->params,"project"); char *pp=obj_path(obj_project(project)); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); USER *u; obj_iter_type_bgn(obj("/users"),u,"user") user_read_temp_groups(u,pp,1); jstr_opn_obj(s); jstr_akey_ustr(s,"login",0,u->login,0); jstr_akey_ustr(s,"icon",0,u->icon,0); jstr_akey_ustr(s,"name",0,u->name,0); jstr_akey_ustr(s,"department",0,u->department,0); jstr_akey_ustr(s,"position",0,u->position,0); if(u->temp_groups && *u->temp_groups){ jstr_akey(s,"groups",0); jstr_opn_arr(s); char **ug=u->temp_groups; while(*ug){ jstr_ustr(s,*ug,0); ug++; } jstr_cls_arr(s); } jstr_cls_obj(s); obj_iter_type_end jstr_cls_arr(s); exit: if(err){ ns_rpc_response_err(r,err); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_editor_hold_object(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; HOLD *h=NULL; char *path=json_str(r->params,"path"); bool force=json_bool(r->params,"force"); if(str_start(path,"/projects/")){ if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } bool ok=acs(u,path,ACS_TYPE_EDIT,1); if(ok){ h=obj_get_editor_hold(path); if(h){ if(strcmp(h->user,u->login)==0){ h->time=time_clock(); }else{ if(force){ HOLD *x=NULL; char *p=strdup(path); while(p && strcmp(p,"/projects")!=0){ x=khash_get(holds,p); file_parent(p); if(x){ khash_delete(holds,x->path); free(x->path); free(x->user); free(x); }; } free(p); h=calloc(1,sizeof(HOLD)); h->path=strdup(path); h->user=strdup(u->login); h->time=time_clock(); khash_set(holds,h->path,h); } } }else{ h=calloc(1,sizeof(HOLD)); h->path=strdup(path); h->user=strdup(u->login); h->time=time_clock(); khash_set(holds,h->path,h); } } } exit: if(err){ ns_rpc_response_err(r,err); }else{ if(h){ JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"path",0,h->path,0); jstr_akey_ustr(s,"user",0,h->user,0); jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); }else{ ns_rpc_response_null(r); } } } void api_fdb_templates(NS_RPC_REQUEST *r){ if(!api_required(r,"dir")) return; char *dir=json_str(r->params,"dir"); char *temp_path=file_subpath(file_here("templates"),dir); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); char *name; char *path; file_iter_bgn(temp_path,FILE_TYPE_DIR,name,path) char *info=file_subpath(path,"info.json"); char *json=file_read_text(info); jstr_ukey_raw(s,name,0,json,0); free(json); free(info); file_iter_end jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); free(temp_path); } void api_fdb_import_template(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"template,path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *template=json_str (r->params,"template"); char *path=json_str (r->params,"path"); char *name=json_str (r->params,"name"); char tp[PATH_MAX]; char *t=NULL; char *fp=NULL; if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } snprintf(tp,PATH_MAX,"%s/%s/%s",file_here("templates"),template,u->language); if(!file_direxists(tp)){ snprintf(tp,PATH_MAX,"%s/%s/%s",file_here("templates"),template,param_language); } if(!file_direxists(tp)){ snprintf(tp,PATH_MAX,"%s/%s",file_here("templates"),template); char *name; char *path; file_iter_bgn(tp,FILE_TYPE_DIR,name,path) snprintf(tp,PATH_MAX,"%s/%s/%s",file_here("templates"),template,name); break; file_iter_end } char *tname; char *tpath; file_iter_bgn(tp,FILE_TYPE_DIR,tname,tpath) t=strdup(tpath); break; file_iter_end if(!t){ err=SERVER_ERROR_OPERATION_FAILED; goto exit; } if(!file_exists(t)){ err_desc=t; err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } if(!obj_exists(path)){ err_desc=path; err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } if(!acs(u,path,ACS_TYPE_EDIT,1)){ err=SERVER_ERROR_ACCESS_DENIED; OBJ *ao=obj_access(path,ACS_TYPE_EDIT); if(ao) err_desc=ao->fo->path; goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } fp=obj_import(t,path,name,1,&err); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_str(r,fp,0); } free(fp); free(t); } void api_cb_fdb_import(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); ns_rpc_parse_outgoing_request(req); char *project=prj_name(json_str(req->params,"payload/project")); char *path=json_str(req->params,"payload/path"); jrnl(r,JRNL_PROJECT_START_IMPORT,"project",project,"error",err,"data",path,NULL); ns_rpc_response_back(r,res); } void api_fdb_import(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"file,path,data")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *file=json_str (r->params,"file"); char *path=json_str (r->params,"path"); char *data=json_str (r->params,"data"); int size=json_size(r->params,"data"); char *project=prj_path(path); char *unpack_command=NULL; char src[PATH_MAX]; char dst[PATH_MAX]; char *dir=NULL; unsigned char *decoded_data=NULL; int32_t decoded_size; if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(!acs(u,path,ACS_TYPE_EDIT,1)){ err=SERVER_ERROR_ACCESS_DENIED; OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); goto exit; } if(!obj_check_editor_hold(path,u->login)){ err=SERVER_ERROR_EDITOR_HOLD_OBJECT; goto exit; } if(!str_end(file,".tgz")){ err=SERVER_ERROR_INVALID_FORMAT; goto exit; } dir=strdup(file); dir[strlen(dir)-4]='\0'; snprintf(src,PATH_MAX,"%s/%s",path_import_dir,file); snprintf(dst,PATH_MAX,"%s/%s",path_import_dir,dir); if(file_exists(src)){ err=SERVER_ERROR_OPERATION_IN_PROGRESS; goto exit; } decoded_data=str_base64_decode((unsigned char*)data,size,&decoded_size); file_write(src,(char*)decoded_data,decoded_size); file_mkpath(dst,0640); unpack_command=str_f("%s \"%s\" \"%s\"",file_here("unpack_backup.sh"),src,dst); //printf("\n\n%s\n\n",unpack_command); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"command",0,unpack_command,0); jstr_akey(s,"payload",0); jstr_opn_obj(s); jstr_akey_uint(s,"cid",0,r->c->id); jstr_akey_ustr(s,"rid",0,r->id,0); jstr_akey_ustr(s,"method",0,r->method,0); jstr_akey_ustr(s,"project",0,project,0); jstr_akey_ustr(s,"path",0,path,0); jstr_akey_ustr(s,"dst",0,dst,0); jstr_akey_ustr(s,"src",0,src,0); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request(srv_exec->c,"async",s->text,s->len,api_cb_fdb_import,r); exit: if(err){ jrnl(r,JRNL_PROJECT_START_IMPORT,"project",project,"error",err,NULL); ns_rpc_response_error(r,err,NULL,err_desc,0); } free(dir); free(decoded_data); free(unpack_command); } void api_cb_fdb_export(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); ns_rpc_parse_outgoing_request(req); char *project=prj_name(json_str(req->params,"payload/project")); char *paths=json_param_stringify(req->params,"payload/paths"); jrnl(r,JRNL_PROJECT_START_EXPORT,"project",project,"error",err,"data",paths,NULL); ns_rpc_response_back(r,res); free(paths); } void api_fdb_export(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; //if(!api_is_write_access(r)) return; if(!api_required(r,"paths")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; JSON *paths=json_tok(r->params,"paths"); char *paths_str=json_stringify_buf(&temp_json_buffer,paths,NULL); char *first=json_tos(paths+1); char *project=prj_path(first); char *pack_command=NULL; char *res=NULL; char src[PATH_MAX]; char dst[PATH_MAX+20]; char *name=NULL; char time[40]; if(paths->count==0){ err=NS_RPC_ERROR_PARAMS; goto exit; }else if(paths->count==1){ char *p=strdup(first); name=strdup(file_title(file_name(p))); free(p); }else{ char *p=file_parent_copy(first); name=strdup(file_title(file_name(p))); free(p); } uint32_t t=time_s(); t--; next: t++; struct tm *ltime=time_local(t); strftime(time,40,"%Y-%m-%d-%H-%M-%S",ltime); snprintf(src,sizeof(src),"%s/%s-%s",path_export_dir,name,time); if(file_direxists(src)) goto next; file_mkpath(src,0640); snprintf(dst,sizeof(dst),"%s.tgz",src); //printf("\n\n%s\n\n",dst); char *p; int i; json_iter_array_str_bgn(paths,i,p) if(u->admin || acs(u,p,ACS_TYPE_EDIT,1)){ char *path=fdb_abs_path(&fdb,p); file_copy_to_dir(path,src,1); } json_iter_array_str_end pack_command=str_f("%s \"%s\" \"%s\"",file_here("pack_backup.sh"),dst,src); char url[PATH_MAX]; snprintf(url,PATH_MAX,"/export/%s",file_name(dst)); res=str_of_str(url); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"command",0,pack_command,0); jstr_akey(s,"payload",0); jstr_opn_obj(s); jstr_akey_uint(s,"cid",0,r->c->id); jstr_akey_ustr(s,"rid",0,r->id,0); jstr_akey_ustr(s,"method",0,r->method,0); jstr_akey_ustr(s,"project",0,project,0); jstr_akey_raw(s,"paths",0,paths_str,0); jstr_akey_ustr(s,"result",0,res,0); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request(srv_exec->c,"async",s->text,s->len,api_cb_fdb_export,r); exit: if(err){ jrnl(r,JRNL_PROJECT_START_EXPORT,"project",project,"error",err,"data",paths_str,NULL); ns_rpc_response_error(r,err,NULL,err_desc,0); } free(pack_command); free(name); free(res); } void api_cb_backup_create(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *project=json_tos(r->params); jrnl(r,JRNL_PROJECT_START_BACKUP,"project",project,"error",err,NULL); ns_rpc_response_back(r,res); } void api_backup_create(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"project")) return; USER *u=api_user(r); int err=0; char time[40]; char src[PATH_MAX]; char dst[PATH_MAX]; char *pack_command=NULL; char *path=NULL; char *err_desc=NULL; char *project=json_str(r->params,"project"); path=str_f("/projects/%s.project",project); if(!obj_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } bool ok=acs(u,path,ACS_TYPE_EDIT,0); if(!ok){ err_desc=path; err=SERVER_ERROR_EDIT_ACCESS_DENIED; goto exit; } uint32_t t=time_s(); t--; next: t++; struct tm *ltime=time_local(t); strftime(time,40,"%Y-%m-%d-%H-%M-%S",ltime); snprintf(src,PATH_MAX,"%s/%s-%s",path_export_dir,project,time); if(file_direxists(src)) goto next; snprintf(dst,PATH_MAX,"%s/%s-%s.tgz",path_backups_dir,project,time); if(file_exists(dst)){ err=SERVER_ERROR_OBJECT_EXISTS; goto exit; } file_mkpath(src,0640); int rc=file_copy_to_dir(fdb_abs_path(&fdb,path),src,1); if(rc!=0){ err=errno; goto exit; } pack_command=str_f("%s \"%s\" \"%s\"",file_here("pack_backup.sh"),dst,src); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"command",0,pack_command,0); jstr_akey(s,"payload",0); jstr_opn_obj(s); jstr_akey_uint(s,"cid",0,r->c->id); jstr_akey_ustr(s,"rid",0,r->id,0); jstr_akey_ustr(s,"method",0,r->method,0); jstr_akey_raw(s,"result",0,"true",0); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request(srv_exec->c,"async",s->text,s->len,api_cb_backup_create,r); exit: if(err){ jrnl(r,JRNL_PROJECT_START_BACKUP,"project",project,"error",err,NULL); ns_rpc_response_error(r,err,NULL,err_desc,0); } free(path); free(pack_command); } void api_cb_backup_restore(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); ns_rpc_parse_outgoing_request(req); char *project=json_str(req->params,"payload/project"); jrnl(r,JRNL_PROJECT_START_RESTORE,"project",project,"error",err,NULL); ns_rpc_response_back(r,res); } void api_backup_restore(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"backup")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *backup=json_str (r->params,"backup"); char *unpack_command=NULL; char *project=NULL; char src[PATH_MAX]; char dst[PATH_MAX]; char *pp=NULL; int len=strlen(backup); if(prj_building){ err=SERVER_ERROR_BUILDING_IN_PROGRESS; goto exit; } if(len<=24){ err=NS_RPC_ERROR_PARAMS; goto exit; } project=strdup(backup); project[len-24]=0; pp=str_f("/projects/%s.project",project); if(!acs(u,pp,ACS_TYPE_EDIT,1)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } snprintf(src,PATH_MAX,"%s/%s",path_backups_dir,backup); if(!file_exists(src)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=src; goto exit; } char *t=file_title_copy(backup); snprintf(dst,PATH_MAX,"%s/%s",path_import_dir,t); free(t); if(file_exists(dst)){ err=SERVER_ERROR_OPERATION_IN_PROGRESS; goto exit; } file_mkpath(dst,0640); unpack_command=str_f("%s \"%s\" \"%s\"",file_here("unpack_backup.sh"),src,dst); //printf("\n\n%s\n\n",unpack_command); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"command",0,unpack_command,0); jstr_akey(s,"payload",0); jstr_opn_obj(s); jstr_akey_uint(s,"cid",0,r->c->id); jstr_akey_ustr(s,"rid",0,r->id,0); jstr_akey_ustr(s,"method",0,r->method,0); jstr_akey_ustr(s,"project",0,project,0); jstr_akey_ustr(s,"dst",0,dst,0); jstr_akey_ustr(s,"src",0,src,0); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request(srv_exec->c,"async",s->text,s->len,api_cb_backup_restore,r); exit: if(err){ jrnl(r,JRNL_PROJECT_START_RESTORE,"project",project,"error",err,NULL); ns_rpc_response_error(r,err,NULL,err_desc,0); } free(pp); free(project); free(unpack_command); } void api_backup_list(NS_RPC_REQUEST *r){ if(!api_is_registered_user(r)) return; //if(!api_required(r,"project")) return; USER *u=api_user(r); //int err=0; char *project=json_str(r->params,"project"); jstr_reset(&temp_str); jstr_opn_arr(&temp_str); char *name; char *path; file_iter_bgn(path_backups_dir,FILE_TYPE_FILE,name,path) int len=strlen(name); if(len>24){ char *n=strdup(name); char *p=n+len-24; p[0]=0; // printf("\n\n%s %s\n\n",n,p); if(!project || strcmp(n,project)==0){ char *pp=str_f("/projects/%s.project",n); if(u->admin || acs(u,pp,ACS_TYPE_EDIT,1)){ jstr_opn_obj(&temp_str); jstr_akey_ustr(&temp_str,"name",0,name,0); jstr_akey_uint(&temp_str,"size",0,file_size(path)); jstr_cls_obj(&temp_str); } free(pp); } free(n); } file_iter_end jstr_cls_arr(&temp_str); ns_rpc_response_raw_result(r,temp_str.text,temp_str.len); } void api_backup_delete(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"backup")) return; USER *u=api_user(r); int err=0; char *path=NULL; char *project=NULL; char *pp=NULL; char *backup=json_str(r->params,"backup"); int len=strlen(backup); if(len<=24){ err=NS_RPC_ERROR_PARAMS; goto exit; } project=strdup(backup); project[len-24]=0; pp=str_f("/projects/%s.project",project); if(!acs(u,pp,ACS_TYPE_EDIT,1)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } path=str_f("%s/%s",path_backups_dir,backup); //printf("\n\n%s -> %s\n\n",path,project); if(!file_exists(path)){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } int rc=file_remove(path); if(rc!=0) err=errno; exit: jrnl(r,JRNL_PROJECT_DELETE_BACKUP,"object",backup,"error",err,NULL); ns_rpc_response(r,err); free(path); free(project); free(pp); } void api_cb_editor_start_build(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *project=json_str(r->params,"project"); jrnl(r,JRNL_PROJECT_START_BUILD,"project",project,"error",err,NULL); ns_rpc_response_back(r,res); } void api_editor_start_build(NS_RPC_REQUEST *r){ if(!api_is_write_access(r)) return; if(!api_is_editor_access(r)) return; //ns_rpc_request_proxy(srv_builder->c,"build_projects",r); int len; char *params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request(srv_builder->c,"build_projects",params,len,api_cb_editor_start_build,r); } void api_cb_editor_cancel_build(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *project=json_str(r->params,"project"); jrnl(r,JRNL_PROJECT_CANCEL_BUILD,"project",project,"error",err,NULL); ns_rpc_response_back(r,res); } void api_editor_cancel_build(NS_RPC_REQUEST *r){ if(!api_is_write_access(r)) return; if(!api_is_editor_access(r)) return; int len; char *params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request(srv_builder->c,"cancel",params,len,api_cb_editor_cancel_build,r); } void api_log_get_server_config(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); char *dir=file_here(".."); char *service; char *path; file_iter_bgn(dir,FILE_TYPE_DIR,service,path) JSTR c; jstr_init(&c,1024); char file[PATH_MAX+20]; snprintf(file,sizeof(file),"%s/config.cfg",path); cfg_get_config_json(file,&c); JSON *j=json_read(c.text,c.len); jstr_akey(s,service,0); jstr_opn_obj(s); JSON *t; char *k; json_iter_object_bgn(j,k,t) if(str_equal(k,"enabled")) jstr_akey_astr(s,k,0,json_tos(t),0); if(str_equal(k,"ENABLED")) jstr_akey_astr(s,k,0,json_tos(t),0); if(str_equal(k,"logger_enabled")) jstr_akey_astr(s,k,0,json_tos(t),0); if(str_equal(k,"logger_write")) jstr_akey_astr(s,k,0,json_tos(t),0); if(str_equal(k,"LOG_ENABLED")) jstr_akey_astr(s,k,0,json_tos(t),0); if(str_start(k,"log_")) jstr_akey_astr(s,k,0,json_tos(t),0); json_iter_object_end jstr_cls_obj(s); json_free(j); jstr_free(&c); file_iter_end jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_log_get_server_schema(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); char *dir=file_here(".."); char *service; char *path; file_iter_bgn(dir,FILE_TYPE_DIR,service,path) JSTR c; jstr_init(&c,1024); char file[PATH_MAX+20]; snprintf(file,sizeof(file),"%s/config.shema",path); cfg_get_schema_json(file,&c); JSON *j=json_read(c.text,c.len); jstr_akey(s,service,0); jstr_opn_obj(s); JSON *t; char *k; json_iter_object_bgn(j,k,t) if(str_start(k,"log_")){ int size; char *data=json_stringify_buf(&temp_json_buffer,t,&size); jstr_akey_raw(s,k,0,data,size); } json_iter_object_end jstr_cls_obj(s); json_free(j); jstr_free(&c); file_iter_end jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_log_get_gateway_config(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_VIEW,1)){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_astr(s,"mac",0,gw->mac,0); jstr_akey_astr(s,"method",0,"get_config",0); jstr_akey(s,"params",0); jstr_opn_obj(s); jstr_akey_astr(s,"part",0,"data",0); jstr_akey(s,"param_names",0); jstr_opn_arr(s); { char **p=gateway_log_coinfig_params; while(*p){ jstr_astr(s,*p,0); p++; } } jstr_cls_arr(s); jstr_akey(s,"services",0); jstr_opn_arr(s); { char **p=gateway_log_config_services; while(*p){ jstr_astr(s,*p,0); p++; } } jstr_cls_arr(s); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request_back(srv_drv_gateway->c,"gateway_api",s->text,s->len,r); exit: if(err) ns_rpc_response_error(r,err,NULL,err_desc,0); } void api_log_get_gateway_schema(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_VIEW,1)){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_astr(s,"mac",0,gw->mac,0); jstr_akey_astr(s,"method",0,"get_config",0); jstr_akey(s,"params",0); jstr_opn_obj(s); jstr_akey_astr(s,"part",0,"schema",0); jstr_akey(s,"param_names",0); jstr_opn_arr(s); { char **p=gateway_log_coinfig_params; while(*p){ jstr_astr(s,*p,0); p++; } } jstr_cls_arr(s); jstr_akey(s,"services",0); jstr_opn_arr(s); { char **p=gateway_log_config_services; while(*p){ jstr_astr(s,*p,0); p++; } } jstr_cls_arr(s); jstr_cls_obj(s); jstr_cls_obj(s); //printf("\n\n%s\n\n",s->text); ns_rpc_request_back(srv_drv_gateway->c,"gateway_api",s->text,s->len,r); exit: if(err) ns_rpc_response_error(r,err,NULL,err_desc,0); } void api_log_set_gateway_config(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path,config")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); JSON *config=json_tok(r->params,"config"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_EDIT,1)){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_astr(s,"mac",0,gw->mac,0); jstr_akey_astr(s,"method",0,"set_config",0); jstr_akey(s,"params",0); jstr_opn_obj(s); char *k; JSON *service; json_iter_object_bgn(config,k,service) bool match=0; char **p=gateway_log_config_services; while(*p){ if(str_match(k,*p)){ match=1; break; } p++; } if(match){ jstr_akey(s,k,0); jstr_opn_obj(s); char *k; JSON *v; json_iter_object_bgn(service,k,v) bool match=0; char **p=gateway_log_coinfig_params; while(*p){ if(str_match(k,*p)){ match=1; break; } p++; } if(match){ jstr_akey_ustr(s,k,0,json_tos(v),0); } json_iter_object_end jstr_cls_obj(s); } json_iter_object_end jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_request_back(srv_drv_gateway->c,"gateway_api",s->text,s->len,r); exit: if(err) ns_rpc_response_error(r,err,NULL,err_desc,0); } void api_gateway_restart_service(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path,service")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); char *service=json_str(r->params,"service"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_EDIT,1)){ OBJ *ao=obj_access(path,ACS_TYPE_EDIT); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_astr(s,"mac",0,gw->mac,0); jstr_akey_astr(s,"method",0,"restart",0); jstr_akey_ustr(s,"params",0,service,0); jstr_cls_obj(s); ns_rpc_request_back(srv_drv_gateway->c,"gateway_api",s->text,s->len,r); exit: if(err) ns_rpc_response_error(r,err,NULL,err_desc,0); } void api_cb_gateway_reset_secret(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *gateway=json_str(r->params,"mac"); jrnl(r,JRNL_GATEWAY_RESET_SECRET,"gateway",gateway,"error",err,NULL); ns_rpc_response_back(r,res); } void api_gateway_reset_secret(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; int len; char *params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request(srv_drv_gateway->c,"gateway_reset_secret",params,len,api_cb_gateway_reset_secret,r); } void api_cb_gateway_exec(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *gateway=json_str(r->params,"mac"); char *data=json_stringify_buf(&temp_json_buffer,r->params,NULL); jrnl(r,JRNL_GATEWAY_EXEC,"gateway",gateway,"data",data,"error",err,NULL); ns_rpc_response_back(r,res); } void api_gateway_exec(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; int len; char *params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request(srv_drv_gateway->c,"gateway_exec",params,len,api_cb_gateway_exec,r); } void api_cb_gateway_reboot(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ NS_RPC_REQUEST *r=cb_data; int err=0; if(res->error) err=json_int(res->error,"code"); char *gateway=json_str(r->params,"mac"); jrnl(r,JRNL_GATEWAY_REBOOT,"gateway",gateway,"error",err,NULL); ns_rpc_response_back(r,res); } void api_gateway_reboot(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; int len; char *params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request(srv_drv_gateway->c,"gateway_reboot",params,len,api_cb_gateway_reboot,r); } void api_gateway_info(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"path")) return; USER *u=api_user(r); int err=0; char *err_desc=NULL; char *path=json_str(r->params,"path"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_VIEW,1)){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; err_desc=path; goto exit; } JSTR *s=&temp_str; jstr_reset(s); gw_get_info_json(gw,s); ns_rpc_response_raw_result(r,s->text,s->len); exit: if(err) ns_rpc_response_error(r,err,NULL,err_desc,0); } void api_gateway_macs(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); GW *gw; khash_iter_bgn(gw_list,gw) jstr_astr(s,gw->mac,0); khash_iter_end jstr_cls_arr(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_license_add(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"key")) return; char *key=json_str(r->params,"key"); int err=license_add(key); if(!err) license_recalc(); ns_rpc_response(r,err); } void api_license_delete(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(!api_required(r,"key")) return; char *key=json_str(r->params,"key"); int err=license_delete(key); if(!err) license_recalc(); ns_rpc_response(r,err); } void api_license_keys(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; int lic_vars=0; jstr_reset(&temp_str); jstr_opn_obj(&temp_str); jstr_akey(&temp_str,"keys",0); jstr_opn_arr(&temp_str); char *name; char *path; file_iter_bgn(path_license_dir,FILE_TYPE_FILE,name,path) char key[54]; int err=license_read(name,key); if(!err){ int vars=license_check(key); if(vars){ lic_vars+=vars; jstr_opn_obj(&temp_str); jstr_akey_astr(&temp_str,"key",0,name,0); jstr_akey_int(&temp_str,"vars",0,vars); jstr_akey_astr(&temp_str,"status",0,"active",0); jstr_akey_int(&temp_str,"added",0,file_modified(path)); jstr_cls_obj(&temp_str); } } file_iter_end jstr_cls_arr(&temp_str); jstr_akey_int(&temp_str,"ttl_vars",0,stat_physical_vars_cnt); jstr_akey_int(&temp_str,"lic_vars",0,lic_vars); jstr_cls_obj(&temp_str); ns_rpc_response_raw_result(r,temp_str.text,temp_str.len); } void api_system_restart_service(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(srv_supervisor->connected){ char *params=json_param_stringify(r->params,"service"); ns_rpc_request_back(srv_supervisor->c,"restart",params,0,r); free(params); }else{ ns_rpc_response_err(r,SERVER_ERROR_SUPERVISOR_OFFLINE); } } void api_system_start_service(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(srv_supervisor->connected){ char *params=json_param_stringify(r->params,"service"); ns_rpc_request_back(srv_supervisor->c,"start",params,0,r); free(params); }else{ ns_rpc_response_err(r,SERVER_ERROR_SUPERVISOR_OFFLINE); } } void api_system_stop_service(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; if(srv_supervisor->connected){ char *params=json_param_stringify(r->params,"service"); ns_rpc_request_back(srv_supervisor->c,"stop",params,0,r); free(params); }else{ ns_rpc_response_err(r,SERVER_ERROR_SUPERVISOR_OFFLINE); } } void api_system_reboot(NS_RPC_REQUEST *r){ if(!api_is_admin(r)) return; if(!api_is_write_access(r)) return; reboot=1; jrnl(r,JRNL_SYSTEM_REBOOT,NULL); ns_rpc_response(r,0); } void api_system_check_cron(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"cron")) return; char *cron=json_str(r->params,"cron"); uint64_t time=0; cron_check(cron,&time); ns_rpc_response_int(r,time); } void api_trends_read(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"vars")) return; int err=0; USER *u=api_user(r); USER_GROUP **ugg=user_groups(u); int len; char *params=NULL; JSON *vars=json_tok(r->params,"vars"); int i; JSON *t; json_iter_array_bgn(vars,i,t) if(t->type==JSON_TYPE_ARRAY){ char *vn=json_tos(t+1); int vi=drv_index_by_name(vn); if(vi>=0){ if(!acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } } } json_iter_array_end params=json_stringify_buf(&temp_json_buffer,vars,&len); ns_rpc_request_back(srv_trends->c,"read",params,len,r); exit: if(err) ns_rpc_response_err(r,err); free(ugg); } void api_trends_log(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"vars")) return; int err=0; USER *u=api_user(r); USER_GROUP **ugg=user_groups(u); int len; char *params=NULL; JSON *vars=json_tok(r->params,"vars"); int i; JSON *t; json_iter_array_bgn(vars,i,t) if(t->type==JSON_TYPE_ARRAY){ char *vn=json_tos(t+1); int vi=drv_index_by_name(vn); if(vi>=0){ if(!acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } } } json_iter_array_end params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request_back(srv_trends->c,"log",params,len,r); exit: if(err) ns_rpc_response_err(r,err); free(ugg); } void api_trends_slice(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_required(r,"vars")) return; int err=0; USER *u=api_user(r); USER_GROUP **ugg=user_groups(u); int len; char *params=NULL; JSON *vars=json_tok(r->params,"vars"); int i; JSON *t; json_iter_array_bgn(vars,i,t) if(t->type==JSON_TYPE_ARRAY){ char *vn=json_tos(t+1); int vi=drv_index_by_name(vn); if(vi>=0){ if(!acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } } } json_iter_array_end params=json_stringify_buf(&temp_json_buffer,r->params,&len); ns_rpc_request_back(srv_trends->c,"slice",params,len,r); exit: if(err) ns_rpc_response_err(r,err); free(ugg); } void api_project_info(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); if(!api_required(r,"path")) return; int err=0; char *err_desc=NULL; char *path=prj_path(json_str(r->params,"path")); bool ok=acs(u,path,ACS_TYPE_VIEW,1); if(!ok){ OBJ *ao=obj_access(path,ACS_TYPE_VIEW); err_desc=obj_path(ao); err=SERVER_ERROR_ACCESS_DENIED; goto exit; } OBJ *o=obj(path); if(!o){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); PROJECT *p=o->payload; if(p){ jstr_akey_int(s,"stat_nodes",0,p->stat_nodes); jstr_akey_int(s,"stat_vars",0,p->stat_vars); jstr_akey_int(s,"stat_virt_vars",0,p->stat_virt_vars); jstr_akey_int(s,"stat_phis_vars",0,p->stat_phis_vars); } jstr_cls_obj(s); exit: if(err){ ns_rpc_response_error(r,err,NULL,err_desc,0); }else{ ns_rpc_response_raw_result(r,s->text,s->len); } } void api_var_get(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); USER_GROUP **ugg=user_groups(u); JSON *vars=json_tok(r->params,"vars"); JSON *nodes=json_tok(r->params,"nodes"); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); if(vars){ if(vars->type==JSON_TYPE_ARRAY){ int i; JSON *t; json_iter_array_bgn(vars,i,t) int vi=-1; if(json_is_str(t)){ vi=drv_index_by_name(json_tos(t)); }else{ vi=json_toi(t); } if(drv_exists(vi) && acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ drv_var_to_str(vi,s); }else{ jstr_raw(s,"null",4); } json_iter_array_end }else{ JSON *t=vars; int vi=-1; if(json_is_str(t)){ vi=drv_index_by_name(json_tos(t)); }else{ vi=json_toi(t); } if(drv_exists(vi) && acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ drv_var_to_str(vi,s); }else{ jstr_raw(s,"null",4); } } } if(nodes){ if(nodes->type==JSON_TYPE_ARRAY){ int i; JSON *t; json_iter_array_bgn(nodes,i,t) char *node=json_tos(t); VAR_NODE *n=NULL; if(!n) n=khash_get(var_node_prefixes,node); if(!n) n=khash_get(var_node_paths,node); if(n && acs(u,n->path,ACS_TYPE_VIEW,1)){ for(int i=0; ivar_cnt; i++){ int vi=n->var_arr[i]; drv_var_to_str(vi,s); } } json_iter_array_end }else{ char *node=json_tos(nodes); VAR_NODE *n=NULL; if(!n) n=khash_get(var_node_prefixes,node); if(!n) n=khash_get(var_node_paths,node); if(n && acs(u,n->path,ACS_TYPE_VIEW,1)){ for(int i=0; ivar_cnt; i++){ int vi=n->var_arr[i]; drv_var_to_str(vi,s); } } } } jstr_cls_arr(s); free(ugg); ns_rpc_response_raw_result(r,s->text,s->len); } void api_var_set(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!param_demo_mode && !api_is_write_access(r)) return; if(!api_required(r,"var")) return; JSON *tvalue=json_tok(r->params,"value"); char *var=json_str(r->params,"var"); double value=tvalue ? json_tod(tvalue) : DRV_UNDEFINED; char *payload=json_param_stringify(r->params,"payload"); var_set(r,var,value,payload,JRNL_EXP_SET_VAR,0); free(payload); } void api_var_info(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; int err=0; char *var=json_str(r->params,"var"); int vi=drv_index_by_name(var); VAR_DATA *vd=drv_var_data(vi); VAR_NODE *n=drv_node_data(vd->nodeid); if(!n){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); if(n->gateway && n->gateway[0]) jstr_akey_astr(s,"gateway",0,n->gateway,0); if(drv_keys_vars){ JKR jkr; jkr_init(&jkr,drv_keys_vars,vd->token); int i; char *k; json_iter_array_str_bgn(drv_keys_vars,i,k) JSON *t=jkr_tok(&jkr,vd->token,k); int len; char *str=json_stringify(t,&len); if(str) jstr_akey_raw(s,k,0,str,len); free(str); json_iter_array_str_end } jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); exit: if(err) ns_rpc_response_err(r,err); } void api_node_prefixes(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); JSON *paths=json_tok(r->params,"paths"); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_arr(s); int i; char *path; json_iter_array_str_bgn(paths,i,path) VAR_NODE *n=khash_get(var_node_paths,path); if(n && acs(u,n->path,ACS_TYPE_VIEW,1)){ jstr_astr(s,n->prefix,n->prefix_len); }else{ jstr_astr(s,"null",0); } json_iter_array_str_end jstr_cls_arr(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_node_list(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); JSON *prefixes=json_tok(r->params,"prefixes"); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_raw(s,"keys",4,node_keys,0); jstr_akey(s,"rows",4); jstr_opn_arr(s); int i; char *prefix; json_iter_array_str_bgn(prefixes,i,prefix) VAR_NODE *n=khash_get(var_node_prefixes,prefix); if(n){ if(acs(u,n->path,ACS_TYPE_VIEW,1)){ jstr_raw(s,n->json_str,n->json_len); } } json_iter_array_str_end jstr_cls_arr(s); jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); } void api_var_list(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); USER_GROUP **ugg=NULL; char *path=json_str(r->params,"path"); JSON *list=json_tok(r->params,"list"); bool alarms=json_bool(r->params,"alarms"); bool strict=json_bool(r->params,"strict"); // return var item or null if no exists int *arr=NULL; int cnt=0; bool free_arr=0; if(list){ char *project_prefix=NULL; char project_prefix_buf[256]; int project_prefix_len=0; char *node_prefix=NULL; char node_prefix_buf[256]; int node_prefix_len=0; if(path){ project_prefix=prj_prefix(prj_path(path)); project_prefix_len=strlen(project_prefix); project_prefix_len=sprintf(project_prefix_buf,"%.*s_",project_prefix_len,project_prefix); VAR_NODE *n=khash_get(var_node_paths,path); if(n){ node_prefix=n->prefix; node_prefix_len=sprintf(node_prefix_buf,"%.*s_",n->prefix_len,n->prefix); } } char *v; int i; if(strict){ cnt=list->count; }else{ json_iter_array_str_bgn(list,i,v) int vi=drv_index_by_name(v); if(vi<0 && project_prefix){ strlcpy(project_prefix_buf+project_prefix_len,v,sizeof(project_prefix_buf)-project_prefix_len); vi=drv_index_by_name(project_prefix_buf); } if(vi<0 && node_prefix){ strlcpy(node_prefix_buf+node_prefix_len,v,sizeof(node_prefix_buf)-node_prefix_len); vi=drv_index_by_name(node_prefix_buf); } if(vi>=0) cnt++; json_iter_array_str_end } arr=malloc(cnt*sizeof(int)); cnt=0; free_arr=1; json_iter_array_str_bgn(list,i,v) int vi=drv_index_by_name(v); if(vi<0 && project_prefix){ strlcpy(project_prefix_buf+project_prefix_len,v,sizeof(project_prefix_buf)-project_prefix_len); vi=drv_index_by_name(project_prefix_buf); } if(vi<0 && node_prefix){ strlcpy(node_prefix_buf+node_prefix_len,v,sizeof(node_prefix_buf)-node_prefix_len); vi=drv_index_by_name(node_prefix_buf); } if(vi>=0 || strict) arr[cnt++]=vi; json_iter_array_str_end }else if(path){ if(alarms){ VEC *ap=khash_get(var_alarm_paths,path); if(ap){ arr=ap->items; cnt=ap->count; } }else{ char *ext=file_ext(path); if(strcmp(ext,"node")==0 || strcmp(ext,"gateway")==0){ VAR_NODE *n=khash_get(var_node_paths,path); if(n){ arr=n->var_arr; cnt=n->var_cnt; } }else if(strcmp(ext,"project")==0){ int projectid=prj_id(path); for(int i=0; iprojectid==projectid){ cnt+=n->var_cnt; } } arr=malloc(cnt*sizeof(int)); cnt=0; free_arr=1; for(int i=0; iprojectid==projectid){ for(int i=0; ivar_cnt; i++){ int idx=n->var_arr[i]; arr[cnt++]=idx; } } } } } }else{ arr=var_index_arr; cnt=var_count; } ugg=user_groups(u); int nodes_cnt=0; int nodes_cap=drv_nodes_count; int *nodes_arr=calloc(nodes_cap,sizeof(int)); int nodeid=-1; JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey(s,"vars",4); jstr_opn_obj(s); jstr_akey_raw(s,"keys",4,var_keys,0); jstr_akey(s,"rows",4); jstr_opn_arr(s); for(int i=0; i=0){ if(acs_var(u,ugg,vi,ACS_TYPE_VIEW)){ VAR_DATA *vd=drv_var_data(vi); jstr_raw(s,vd->json_str,vd->json_len); if(nodeid!=vd->nodeid){ nodeid=vd->nodeid; if(nodes_cnt>=nodes_cap){ nodes_cap=nodes_cap*2; nodes_arr=realloc(nodes_arr,nodes_cap*sizeof(int)); } nodes_arr[nodes_cnt++]=vd->nodeid; } } }else{ jstr_raw(s,NULL,0); } } jstr_cls_arr(s); jstr_cls_obj(s); jstr_akey(s,"nodes",5); jstr_opn_obj(s); jstr_akey_raw(s,"keys",4,node_keys,0); jstr_akey(s,"rows",4); jstr_opn_arr(s); for(int i=0; ijson_str,n->json_len); } jstr_cls_arr(s); jstr_cls_obj(s); jstr_cls_obj(s); ns_rpc_response_raw_result(r,s->text,s->len); free(nodes_arr); if(free_arr) free(arr); free(ugg); } void api_journal(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; USER *u=api_user(r); int err=0; bool access=u->admin; if(!access){ JSON *filter=json_tok(r->params,"filter"); int i; JSON *f; json_iter_array_bgn(filter,i,f) if(f && f->type==JSON_TYPE_ARRAY && f->count>=3){ char *param=json_tos(f+1); char *comp=json_tos(f+2); JSON *vals=f+3; if(vals && vals->type==JSON_TYPE_ARRAY && vals->count==1){ char *val=json_tos(vals+1); if(str_cmp(param,"project")==0 && str_cmp(comp,"LIKE")==0 && val){ char path[PATH_MAX]; snprintf(path,sizeof(path),"/projects/%s.project/journal",val); access=acs(u,path,ACS_TYPE_VIEW,1); goto exit; }else if(str_cmp(param,"gateway")==0 && str_cmp(comp,"LIKE")==0 && val){ char *mac=val; GW *gw=gw_get_gw(mac); if(gw){ for(int i=0; ipaths.count; i++){ char *p = *(char**)vec(&gw->paths,i); access=acs(u,p,ACS_TYPE_VIEW,1); goto exit; } } access=1; } } } json_iter_array_end } exit: if(!access) err=SERVER_ERROR_ACCESS_DENIED; if(err){ ns_rpc_response_err(r,err); }else{ ns_rpc_request_proxy(srv_db->c,"journal_read",r); } } void api_script_debug(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!api_is_write_access(r)) return; ns_rpc_request_proxy(srv_script->c,"debug",r); } void api_alarm_ack(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!param_demo_mode && !api_is_write_access(r)) return; if(!api_required(r,"var")) return; USER *u=api_user(r); char *ip=ns_rpc_get_remote_ip(r->c); char *user=str_of_str(u->login); char *var=json_str(r->params,"var"); int value=0x101; char *payload=str_f("{\"us\":%s,\"ip\":\"%s\"}",user,ip); var_set(r,var,value,payload,JRNL_EXP_ACK_ALARM,1); free(payload); free(user); } void api_alarm_unack(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!param_demo_mode && !api_is_write_access(r)) return; if(!api_required(r,"var")) return; USER *u=api_user(r); char *ip=ns_rpc_get_remote_ip(r->c); char *user=str_of_str(u->login); char *var=json_str(r->params,"var"); int value=0x102; char *payload=str_f("{\"us\":%s,\"ip\":\"%s\"}",user,ip); var_set(r,var,value,payload,JRNL_EXP_UNACK_ALARM,1); free(payload); free(user); } void api_alarm_shelve(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!param_demo_mode && !api_is_write_access(r)) return; if(!api_required(r,"var")) return; USER *u=api_user(r); char *ip=ns_rpc_get_remote_ip(r->c); char *user=str_of_str(u->login); char *var=json_str(r->params,"var"); int value=0x103; uint32_t period=json_int(r->params,"period"); char *payload=str_f("{\"us\":%s,\"ip\":\"%s\",\"sh\":%u}",user,ip,period); var_set(r,var,value,payload,JRNL_EXP_SHELVE_ALARM,1); free(payload); free(user); } void api_alarm_unshelve(NS_RPC_REQUEST *r){ if(!api_is_user(r)) return; if(!param_demo_mode && !api_is_write_access(r)) return; if(!api_required(r,"var")) return; USER *u=api_user(r); char *ip=ns_rpc_get_remote_ip(r->c); char *user=str_of_str(u->login); char *var=json_str(r->params,"var"); int value=0x104; char *payload=str_f("{\"us\":%s,\"ip\":\"%s\"}",user,ip); var_set(r,var,value,payload,JRNL_EXP_SHELVE_ALARM,1); free(payload); free(user); } void api_test(NS_RPC_REQUEST *r){ int err=0; char *path=strdup("/projects/new.node"); char *parent=fdb_parent_path(path); printf("\n\n%s %s\n\n",parent,path); char *type=obj_type_ex(path,1); printf("\n\n%s\n\n",type); if(!type){ err=SERVER_ERROR_UNKNOWN_TYPE; if(err) goto exit; } // if type ok then copy dir FDB_OBJ *o=fdb_get_obj(&fdb,parent); FDB_OBJ *ch=fdb_scan(&fdb,path,0); if(ch){ ch->parent=o; khash_set(o->children,ch->path,ch); } exit: free(path); ns_rpc_response(r,err); } void api_cb_db_count_notification(NS_RPC_REQUEST *req, NS_RPC_RESPONSE *res, void *cb_data){ char *skey=cb_data; if(!res->error){ NS_RPC_SUBSCRIPTION *s=ns_rpc_get_subscription(skey); if(s){ int len; char *data=json_stringify_buf(&temp_json_buffer, res->result,&len); ns_rpc_subscription_data(s,NULL,data,len); } } free(skey); } void api_cb_user_notifications_subscribed(NS_RPC_SUBSCRIPTION *s){ USER *u=api_user_con(s->c); USER_SESSION *us=api_session_con(s->c); if(us && u && !u->anonymous){ char *tok=user_gettok(us->token); char *params=str_f("{\"user\":\"%s\",\"tok\":\"%s\"}",u->login,tok); ns_rpc_request(srv_db->c,"notification_count",params,0,api_cb_db_count_notification,strdup(s->key)); free(params); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_builder_status_event(NS_RPC_SUBSCRIPTION *rs, void *cb_data){ int len; char *data=json_stringify_buf(&temp_json_buffer,rs->data,&len); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"action",0,"status",0); jstr_akey_raw(s,"status",0,data,len); jstr_cls_obj(s); ns_rpc_subscription_data(NULL,"builder",s->text,s->len); //printf("\n\n%s %u\n\n","builder status",s->len); } void api_cb_builder_signal_event(NS_RPC_SUBSCRIPTION *rs, void *cb_data){ char *data=json_tos(rs->data); JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_ustr(s,"action",0,"signal",0); jstr_akey_ustr(s,"signal",0,data,0); jstr_cls_obj(s); ns_rpc_subscription_data(NULL,"builder",s->text,s->len); //printf("\n\n%s %s\n\n","builder signal",s->text); if(str_cmp(data,"building_vars_started")==0){ prj_building=1; }else if(str_cmp(data,"building_vars_finished")==0){ prj_building=0; // acs_clear_cache(); // prj_reload_vars(); drv_load_vars(); gw_reload_list(); prj_need_build(0); prj_need_refresh(1); prj_update_objects_data(); user_invalidate_groups(); // var_unload(); // var_upload(); } } void api_cb_builder_subscribed(NS_RPC_SUBSCRIPTION *s){ USER *u=api_user_con(s->c); if(u && u->editor_access){ // ok prj_need_build_update(u); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_alarms_subscribed(NS_RPC_SUBSCRIPTION *s){ USER *u=api_user_con(s->c); if(u){ alarm_process_subscription(s,1); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_user_update_subscribed(NS_RPC_SUBSCRIPTION *s){ char *login=json_str(s->options,"login"); USER *u=api_user_con(s->c); if(u && (api_is_admin_con(s->c) || str_equal(login,u->login))){ // ok }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_license_subscribed(NS_RPC_SUBSCRIPTION *s){ license_update_subscriptions(s); } void api_cb_session_update_subscribed(NS_RPC_SUBSCRIPTION *s){ char *login=json_str(s->options,"login"); USER *u=api_user_con(s->c); if(api_is_admin_con(s->c) || str_equal(login,u->login)){ // ok }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_log_event(NS_RPC_SUBSCRIPTION *rs, void *cb_data){ int len; if(rs->error){ int code=json_int(rs->error,"code"); char *message=json_str(rs->error,"message"); ns_rpc_subscription_close(NULL,"log",code,message); }else{ char *data=json_stringify_buf(&temp_json_buffer,rs->data,&len); ns_rpc_subscription_data(NULL,"log",data,len); } } void api_subscribe_log(){ ns_rpc_api_log_next_subscription("event","$events","data"); ns_rpc_subscribe(srv_log_viewer->c,"log",NULL,NULL,0,api_cb_log_event,NULL); } void api_unsubscribe_log(){ ns_rpc_api_log_next_subscription("event","$events","data"); ns_rpc_unsubscribe(srv_log_viewer->c,"log",NULL,NULL,0,api_cb_log_event,NULL); } void api_cb_log_subscribed(NS_RPC_SUBSCRIPTION *s){ if(api_is_admin_con(s->c)){ if(ns_rpc_subscription_count("log")==1) api_subscribe_log(); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_log_unsubscribed(NS_RPC_SUBSCRIPTION *s){ if(ns_rpc_subscription_count("log")==1) api_unsubscribe_log(); } void api_cb_gateway_log_subscribed(NS_RPC_SUBSCRIPTION *s){ int err=0; USER *u=api_user_con(s->c); char *path=json_str(s->options,"path"); GW *gw=gw_get_gw_by_path(path); if(!acs(u,path,ACS_TYPE_VIEW,1)){ err=SERVER_ERROR_ACCESS_DENIED; goto exit; } if(!gw){ err=SERVER_ERROR_OBJECT_NOT_FOUND; goto exit; } JSTR *t=&temp_str; jstr_reset(t); jstr_opn_obj(t); jstr_akey_astr(t,"mac",0,gw->mac,0); jstr_cls_obj(t); ns_rpc_subscribe_proxy(srv_drv_gateway->c,"gateway_log",t->text,t->len,s); exit: if(err) ns_rpc_subscription_close(s,NULL,err,NULL); } void api_cb_gateway_log_unsubscribed(NS_RPC_SUBSCRIPTION *s){ ns_rpc_unsubscribe_proxy(srv_drv_gateway->c,"gateway_log",NULL,0,s); } void api_cb_scheduler_setvar_event(NS_RPC_SUBSCRIPTION *rs, void *cb_data){ register_schedule(rs->data); } void api_cb_exec_event(NS_RPC_SUBSCRIPTION *rs, void *cb_data){ if(rs->data){ int code=json_int(rs->data,"code"); char *output=json_str(rs->data,"output"); uint32_t cid=json_int(rs->data,"payload/cid"); char *rid=json_str(rs->data,"payload/rid"); char *method=json_str(rs->data,"payload/method"); char *result=json_str(rs->data,"payload/result"); int count; NS_RPC_SUBSCRIPTION **ss=ns_rpc_get_subscriptions(cid,"async",0,&count); if(count){ JSTR *s=&temp_str; jstr_reset(s); jstr_opn_obj(s); jstr_akey_raw(s,"id",0,rid,0); if(code==0){ if(str_cmp(method,"fdb_import")==0){ char *src=json_str(rs->data,"payload/src"); char *dst=json_str(rs->data,"payload/dst"); char *path=json_str(rs->data,"payload/path"); jstr_akey(s,"result",0); jstr_opn_arr(s); char *n; char *p; int e; file_iter_bgn(dst,FILE_TYPE_ANY,n,p) char *fp=obj_import(p,path,NULL,0,&e); jstr_opn_obj(s); jstr_akey_ustr(s,"import",0,n,0); jstr_akey_ustr(s,"path",0,fp,0); if(e) jstr_akey_int(s,"error",0,e); jstr_cls_obj(s); free(fp); file_iter_end jstr_cls_arr(s); file_remove(dst); file_remove(src); //printf("\n\n%s\n\n",s->text); }else if(str_cmp(method,"backup_restore")==0){ char *dst=json_str(rs->data,"payload/dst"); char *path="/projects"; jstr_akey(s,"result",0); jstr_opn_arr(s); char *n; char *p; int e; file_iter_bgn(dst,FILE_TYPE_ANY,n,p) char pp[PATH_MAX]; snprintf(pp,PATH_MAX,"%s/%s",path,n); if(obj_exists(pp)){ obj_delete(pp); } char *fp=obj_import(p,path,NULL,0,&e); jstr_opn_obj(s); jstr_akey_ustr(s,"import",0,n,0); jstr_akey_ustr(s,"path",0,fp,0); if(e) jstr_akey_int(s,"error",0,e); jstr_cls_obj(s); free(fp); file_iter_end jstr_cls_arr(s); file_remove(dst); //printf("\n\n%s\n\n",s->text); }else{ jstr_akey_raw(s,"result",0,result,0); } }else{ jstr_akey(s,"error",0); jstr_opn_obj(s); jstr_akey_int(s,"code",0,SERVER_ERROR_OPERATION_FAILED); jstr_akey_astr(s,"message",0,"SERVER_ERROR_OPERATION_FAILED",0); jstr_akey_ustr(s,"data",0,output,0); jstr_cls_obj(s); if(str_cmp(method,"fdb_import")==0){ char *src=json_str(rs->data,"payload/src"); char *dst=json_str(rs->data,"payload/dst"); file_remove(dst); file_remove(src); } } jstr_cls_obj(s); for(int i=0; itext,s->len); } } free(ss); // if(str_cmp(method,"restore_backup")==0){ // acs_clear_cache(); // gw_reload_list(); // prj_reload_vars(); // } } } void api_cb_gateway_info_subscribed(NS_RPC_SUBSCRIPTION *s){ if(!api_is_admin_con(s->c)) ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); //if(!srv_core->connected) ns_rpc_subscription_close(s,NULL,SERVER_ERROR_CORE_OFFLINE,NULL); if(srv_drv_gateway->connected){ gw_fire_info(s); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_DRV_GATEWAY_OFFLINE,NULL); } } void api_cb_ddos_subscribed(NS_RPC_SUBSCRIPTION *s){ if(api_is_admin_con(s->c)){ update_ddos_subs(s,NULL,0); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_var_update_subscribed(NS_RPC_SUBSCRIPTION *s){ USER *u=api_user_con(s->c); if(u){ drv_ex_api_subscribe_update(s); }else{ ns_rpc_subscription_close(s,NULL,SERVER_ERROR_ACCESS_DENIED,NULL); } } void api_cb_var_update_unsubscribed(NS_RPC_SUBSCRIPTION *s){ drv_ex_api_unsubscribe_update(s); } void api_cb_aggregate_subscribed(NS_RPC_SUBSCRIPTION *s){ //s->options int err=0; USER *u=api_user_con(s->c); if(!(u && u->admin) && !s->c->is_unix){ err=SERVER_ERROR_ADMIN_ACCESS_REQUIRED; goto exit; } // char *tag_filter=json_str(s->options,"tag_filter"); // if(!tag_filter){ // err=NS_RPC_ERROR_PARAMS; // goto exit; // } var_free_aggr(s->cb_data); VAR_AGGR *a=calloc(1,sizeof(VAR_AGGR)); char *function=json_str(s->options,"function"); char *cron=str_dup(json_str(s->options,"cron")); a->change_id=-1; a->tag_filter=str_dup(json_str(s->options,"tag_filter")); a->val_filter=str_dup(json_str(s->options,"val_filter")); a->val_expr=str_dup(json_str(s->options,"val_expr")); a->prefix=str_dup(json_str(s->options,"prefix")); a->unrel=json_int_def(s->options,"unrel",0); a->period=json_int_def(s->options,"period",1000); a->var=str_dup(json_str(s->options,"var")); a->varindex=drv_index_by_name(a->var); if(!function) function="summ"; a->function=str_dup(function); if(cron){ a->cron=malloc(sizeof(cron_expr)); cron_parse_cron(cron,a->cron); } s->cb_data=a; if(!a->cron && !a->period) a->period=1000; var_aggregate_update(s); exit: if(err) ns_rpc_subscription_close(s,NULL,err,NULL); } void api_cb_aggregate_unsubscribed(NS_RPC_SUBSCRIPTION *s){ var_free_aggr(s->cb_data); } void api_free(){ } void api_init(){ ns_rpc_on_api_request = api_cb_ns_rpc_api_request; ns_rpc_on_api_response = api_cb_ns_rpc_api_response; service_api("system_ping",api_system_ping,NULL,NULL,"result"); service_api("system_ready",api_system_ready,NULL,NULL,"result"); service_api("system_get_calendar",api_system_get_calendar,NULL,NULL,"result"); service_api("system_set_calendar",api_system_set_calendar,NULL,NULL,"result"); service_api("system_time",api_system_time,NULL,NULL,"result"); service_api("system_reset_time",api_system_reset_time,NULL,"params","result"); service_api("system_set_time",api_system_set_time,NULL,"params","result"); service_api("system_html_files",api_system_html_files,NULL,"folder","result"); service_api("system_info",api_system_info,NULL,NULL,"result"); service_api("system_access",api_system_access,NULL,"params","result"); service_api("system_groups",api_system_groups,NULL,"params","result"); service_api("system_set_config",api_system_set_config,NULL,"params","result"); service_api("system_reset_config",api_system_reset_config,NULL,"params","result"); service_api("system_check_config",api_system_check_config,NULL,"params","result"); service_api("system_info",api_system_info,NULL,NULL,"result"); service_api("system_services",api_system_services,NULL,NULL,"result"); service_api("system_config_data",api_system_config_data,NULL,"service","result"); service_api("system_config_schema",api_system_config_schema,NULL,"service","result"); service_api("system_log_files",api_system_log_files,NULL,"service","result"); service_api("system_delete_logs",api_system_delete_logs,NULL,"service","result"); service_api("system_start_service",api_system_start_service,NULL,NULL,"result"); service_api("system_stop_service",api_system_stop_service,NULL,NULL,"result"); service_api("system_restart_service",api_system_restart_service,NULL,NULL,"result"); service_api("system_reboot",api_system_reboot,NULL,NULL,"result"); service_api("system_check_cron",api_system_check_cron,NULL,NULL,"result"); service_api("editor_hold_object",api_editor_hold_object,NULL,"params","result"); service_api("editor_group_users",api_editor_group_users,NULL,"params","result"); service_api("editor_start_build",api_editor_start_build,NULL,NULL,"result"); service_api("editor_cancel_build",api_editor_cancel_build,NULL,NULL,"result"); service_api("fdb_create",api_fdb_create,NULL,"params","result"); service_api("fdb_create_next",api_fdb_create_next,NULL,"params","result"); service_api("fdb_move",api_fdb_move,NULL,"params","result"); service_api("fdb_clone",api_fdb_clone,NULL,"params","result"); service_api("fdb_copy",api_fdb_copy,NULL,"params","result"); service_api("fdb_delete",api_fdb_delete,NULL,"params","result"); service_api("fdb_save",api_fdb_save,NULL,"params","result"); service_api("fdb_list",api_fdb_list,NULL,"params","result"); service_api("fdb_load",api_fdb_load,NULL,"params","result"); service_api("fdb_access",api_fdb_access,NULL,"params","result"); service_api("fdb_list_doc",api_fdb_list_doc,NULL,"params","result"); service_api("fdb_load_doc",api_fdb_load_doc,NULL,"params","result"); service_api("fdb_save_doc",api_fdb_save_doc,NULL,"params","result"); service_api("fdb_upload",api_fdb_upload,NULL,"params","result"); service_api("fdb_paths",api_fdb_paths,NULL,"params","result"); service_api("fdb_bundle",api_fdb_bundle,NULL,"params","result"); service_api("fdb_prototype_nodes",api_fdb_prototype_nodes,NULL,"params","result"); service_api("fdb_mimic_objects",api_fdb_mimic_objects,NULL,"params","result"); service_api("fdb_export",api_fdb_export,NULL,"params","result"); service_api("fdb_import",api_fdb_import,NULL,"params","result"); service_api("fdb_import_template",api_fdb_import_template,NULL,"params","result"); service_api("fdb_templates",api_fdb_templates,NULL,"params","result"); service_api("fdb_nextname",api_fdb_nextname,NULL,"params","result"); service_api("fdb_search",api_fdb_search,NULL,"params","result"); service_api("user_login",api_user_login,NULL,"params","result"); service_api("user_tokin",api_user_tokin,NULL,"login,browser","result"); service_api("user_get",api_user_get,NULL,"login","result"); service_api("user_changepass",api_user_changepass,NULL,"login","result"); service_api("user_logout",api_user_logout,NULL,NULL,"result"); service_api("user_sessions",api_user_sessions,NULL,"login","result"); service_api("user_active",api_user_active,NULL,NULL,"result"); service_api("user_close_session",api_user_close_session,NULL,"login,tok","result"); service_api("user_save_profile",api_user_save_profile,NULL,"login","result"); service_api("user_list",api_user_list,NULL,"","result"); service_api("user_save",api_user_save,NULL,"new_login,admin","result"); service_api("user_create",api_user_create,NULL,"login,admin","result"); service_api("user_block",api_user_block,NULL,"login","result"); service_api("user_unblock",api_user_unblock,NULL,"login","result"); service_api("user_resetpass",api_user_resetpass,NULL,"login","result"); service_api("user_delete",api_user_delete,NULL,"login","result"); service_api("user_notifications",api_user_notifications,NULL,"params","result"); service_api("user_notifications_watched",api_user_notifications_watched,NULL,NULL,"result"); service_api("backup_create",api_backup_create,NULL,"params","result"); service_api("backup_list",api_backup_list,NULL,"params","result"); service_api("backup_delete",api_backup_delete,NULL,"params","result"); service_api("backup_restore",api_backup_restore,NULL,"params","result"); service_api("gateway_reset_secret",api_gateway_reset_secret,NULL,"mac","result"); service_api("gateway_exec",api_gateway_exec,NULL,"mac,command","result"); service_api("gateway_reboot",api_gateway_reboot,NULL,"mac,command","result"); service_api("gateway_info",api_gateway_info,NULL,"params","result"); service_api("gateway_macs",api_gateway_macs,NULL,"params","result"); service_api("gateway_restart_service",api_gateway_restart_service,NULL,"params","result"); service_api("log_get_server_config",api_log_get_server_config,NULL,"params","result"); service_api("log_get_server_schema",api_log_get_server_schema,NULL,"params","result"); service_api("log_set_server_config",api_system_set_config,NULL,"params","result"); service_api("log_get_gateway_config",api_log_get_gateway_config,NULL,"params","result"); service_api("log_get_gateway_schema",api_log_get_gateway_schema,NULL,"params","result"); service_api("log_set_gateway_config",api_log_set_gateway_config,NULL,"params","result"); service_api("node_list",api_node_list,NULL,"params","result"); service_api("node_prefixes",api_node_prefixes,NULL,"params","result"); service_api("var_list",api_var_list,NULL,"path,list,alarms","result"); service_api("var_set",api_var_set,NULL,"params","result"); service_api("var_get",api_var_get,NULL,"params","result"); service_api("var_info",api_var_info,NULL,"params","result"); service_api("trends_read",api_trends_read,NULL,"params","result"); service_api("trends_log",api_trends_log,NULL,"params","result"); service_api("trends_slice",api_trends_slice,NULL,"params","result"); service_api("license_keys",api_license_keys,NULL,NULL,"result"); service_api("license_add",api_license_add,NULL,NULL,"result"); service_api("license_delete",api_license_delete,NULL,NULL,"result"); service_api("journal",api_journal,NULL,"project","result"); service_api("alarm_ack",api_alarm_ack,NULL,"var","result"); service_api("alarm_unack",api_alarm_unack,NULL,"var","result"); service_api("alarm_shelve",api_alarm_shelve,NULL,"var","result"); service_api("alarm_unshelve",api_alarm_unshelve,NULL,"var","result"); service_api("script_debug",api_script_debug,NULL,"params","result"); service_api("project_info",api_project_info,NULL,"params","result"); service_api("ddos_forget",api_ddos_forget,NULL,"params","result"); service_api("ddos_block",api_ddos_block,NULL,"params","result"); service_api("ddos_unblock",api_ddos_unblock,NULL,"params","result"); service_api("schedule_list",api_schedule_list,NULL,NULL,"result"); service_api("test",api_test,NULL,"params","result"); service_subscription("license",api_cb_license_subscribed,NULL,NULL); service_subscription("user_update",api_cb_user_update_subscribed,NULL,NULL); service_subscription("session_update",api_cb_session_update_subscribed,NULL,NULL); service_subscription("user_notifications",api_cb_user_notifications_subscribed,NULL,NULL); service_subscription("async",NULL,NULL,"data"); service_subscription("builder",api_cb_builder_subscribed,NULL,"data"); service_subscription("alarms",api_cb_alarms_subscribed,NULL,"data"); service_subscription("refresh_interface",NULL,NULL,"data"); service_subscription("journal_update",NULL,NULL,"data"); service_subscription("log",api_cb_log_subscribed,api_cb_log_unsubscribed,"data"); service_subscription("gateway_info",api_cb_gateway_info_subscribed,NULL,"data"); service_subscription("gateway_log",api_cb_gateway_log_subscribed,api_cb_gateway_log_unsubscribed,"data"); service_subscription("var_update",api_cb_var_update_subscribed,api_cb_var_update_unsubscribed,"data"); service_subscription("aggregate",api_cb_aggregate_subscribed,api_cb_aggregate_unsubscribed,"data"); service_subscription("ddos",api_cb_ddos_subscribed,NULL,"data"); }
  Email
   fdb_list
   fdb_load
   fdb_move
   fdb_paths
   node_list
   subscribe
   user_list
   user_save
   var_get
   var_list
   var_set